Day 1
ตั้งค่าเครื่องมือ + สร้าง API ตัวแรก
เวลา: 120 นาที
จบคาบนี้จะได้: เปิด http://localhost:3000/api/books แล้วเห็นข้อมูลหนังสือ
⚠️ อ่านก่อนเริ่ม
- จำหมายเลขเครื่องของตัวเอง แล้วนั่งเครื่องเดิมทุกคาบ โปรเจกต์และฐานข้อมูลจะอยู่บนเครื่องนี้ตลอดเทอม (เครื่องไม่รีเซ็ตเมื่อรีบูต งานจะยังอยู่)
ช่วงที่ 1 — เตรียมเครื่อง (25 นาที)
🗺️ ตำแหน่งตอนนี้ในระบบ
- 🟢 เตรียมเครื่องมือ ← กำลังทำช่วงนี้
- ⚪ Angular (หน้าบ้าน) (ยังไม่ถึง)
- ⚪ NestJS (หลังบ้าน) (ยังไม่ถึง)
- ⚪ PostgreSQL (ฐานข้อมูล) (ยังไม่ถึง)
ต่อไป: เปิดโปรเจกต์ตั้งต้นแล้วรันหลังบ้านให้ทำงานครั้งแรก
1.1 ติดตั้งเครื่องมือ 2 ตัว
ตัวที่หนึ่ง — Node.js 24 LTS
ทำไมต้องมี: เป็นโปรแกรมที่ทำให้รันภาษา JavaScript บนเครื่องเราได้ ปกติ JavaScript รันได้แต่ในเบราว์เซอร์ Node.js ทำให้มันรันเป็นโปรแกรมเดี่ยว ๆ บนเครื่องได้ ทั้ง NestJS และ Angular ต้องอาศัยตัวนี้ทำงาน
- เปิดเบราว์เซอร์ไปที่ nodejs.org
- หน้าแรกจะมีปุ่มดาวน์โหลดสองปุ่ม ให้กดปุ่มที่เขียนว่า LTS (มีคำว่า Recommended for Most Users กำกับอยู่) ห้ามกดปุ่ม Current เด็ดขาด แม้จะเขียนเลขเวอร์ชันสูงกว่าก็ตาม เพราะ Current คือรุ่นทดลองที่ยังไม่เสถียร
- ไฟล์ที่ได้จะชื่อประมาณ
node-v24.x.x-x64.msi(ลงท้ายด้วย x64 แปลว่าเป็นรุ่น 64 บิต ซึ่งตรงกับเครื่องแลปเกือบทุกเครื่อง) - ดับเบิลคลิกไฟล์ที่ดาวน์โหลดมาเพื่อเริ่มติดตั้ง
ระหว่างติดตั้ง จะเจอหน้าจอเรียงกันแบบนี้ ให้ทำตาม:
| หน้าจอ | ต้องทำอะไร |
|---|---|
| Welcome | กด Next |
| End-User License Agreement | ติ๊ก "I accept the terms..." แล้วกด Next |
| Destination Folder | ปล่อยเป็นค่า default (C:\Program Files\nodejs\) กด Next |
| Custom Setup | ปล่อยทุกอย่างเป็นค่า default กด Next — อย่าไปปิดตัวเลือกไหน |
| Tools for Native Modules | ถ้ามีกล่องติ๊กเขียนว่า Automatically install the necessary tools ไม่ต้องติ๊ก (ไม่จำเป็นสำหรับวิชานี้ และจะทำให้ติดตั้งช้าลงมาก เพราะมันจะไปโหลด Visual Studio Build Tools เพิ่ม) |
| Ready to Install | กด Install |
| จบการติดตั้ง | กด Finish |
⚠️ ต้องเป็น Node.js เวอร์ชัน 24 เท่านั้น เวอร์ชัน 22 จะทำให้ Angular ในคาบที่ 3 ใช้งานไม่ได้เลย ไม่ใช่แค่เตือน แต่ปฏิเสธไม่ยอมทำงาน
💡 npm ติดมากับ Node.js อัตโนมัติในตัวติดตั้งเดียวกัน ไม่ต้องไปหาโหลดแยก — เป็นเหมือนร้านขายเครื่องมือสำเร็จรูป เวลาเราต้องการของที่คนอื่นเขียนไว้แล้ว ก็สั่ง npm ไปหยิบมาให้
ตัวที่สอง — VS Code
ทำไมต้องมี: เป็นโปรแกรมที่เราใช้พิมพ์โค้ดตลอดทั้งเทอม
- เปิดเบราว์เซอร์ไปที่ code.visualstudio.com
- กดปุ่มดาวน์โหลดสีน้ำเงินตรงกลางหน้า (จะดาวน์โหลดตัวติดตั้งของ Windows ให้อัตโนมัติ)
- ดับเบิลคลิกไฟล์ที่ได้ (ชื่อประมาณ
VSCodeUserSetup-x64-x.xx.x.exe)
ระหว่างติดตั้ง จุดที่ต้องระวังเป็นพิเศษ:
| หน้าจอ | ต้องทำอะไร |
|---|---|
| License Agreement | เลือก "I accept the agreement" กด Next |
| Select Destination Location | ปล่อยค่า default กด Next |
| Select Additional Tasks | นี่คือหน้าจอสำคัญที่สุด — ต้องติ๊กช่อง "Add to PATH" ให้ครบ (บางเวอร์ชันเขียนว่า "Add "Open with Code" action" ติ๊กได้ตามสบาย แต่ "Add to PATH" ต้องติ๊กเสมอ) |
| Ready to Install | กด Install |
| จบการติดตั้ง | ติ๊กหรือไม่ติ๊ก "Launch Visual Studio Code" ก็ได้ แล้วกด Finish |
⚠️ ทำไม "Add to PATH" ถึงสำคัญมาก ถ้าไม่ติ๊กช่องนี้ พิมพ์คำสั่ง
code .ใน PowerShell ภายหลังจะไม่ทำงาน (ขึ้นว่าis not recognizedเหมือนตอนลืมติดตั้ง Node) ต้องไปถอนแล้วติดตั้งใหม่ ถ้าพลาดไปแล้วให้ถอนการติดตั้ง (Settings → Apps) แล้วโหลดตัวติดตั้งมาลงใหม่ คราวนี้อย่าลืมติ๊ก
1.2 ตรวจว่าติดตั้งสำเร็จ
เปิด PowerShell (กดปุ่ม Windows แล้วพิมพ์ powershell)
💡 Terminal / PowerShell คือหน้าจอที่เราพิมพ์คำสั่งสั่งงานคอมพิวเตอร์ตรง ๆ แทนการคลิกเมาส์ นักพัฒนาใช้ตลอดเวลาเพราะเร็วกว่า
node -v
npm -v
code --version
✅ ต้องเห็น
v24.x.x ← ถ้าเป็น v22 ให้ถอนแล้วติดตั้งใหม่
10.x.x
1.xx.x ← เลขเวอร์ชันของ VS Code ตามด้วยอีก 2 บรรทัดเป็นรหัส commit และสถาปัตยกรรมเครื่อง
❌ ถ้าขึ้น is not recognized ตัวใดตัวหนึ่ง → ปิดหน้าต่าง PowerShell ทั้งหมดแล้วเปิดใหม่ก่อน (เครื่องเพิ่งรู้จักโปรแกรมใหม่ หน้าต่างเก่าที่เปิดค้างไว้จะยังไม่เห็น)
❌ ถ้าเปิดหน้าต่างใหม่แล้วยังไม่หาย → แปลว่าตอนติดตั้งไม่ได้ติ๊ก "Add to PATH" (สำหรับ VS Code) ให้ถอนแล้วลงใหม่ตามขั้นตอนข้างบน หรือสำหรับ Node.js ให้ลองรันตัวติดตั้งซ้ำแล้วเลือก "Repair"
ช่วงที่ 2 — เปิดโปรเจกต์ (25 นาที)
🗺️ ตำแหน่งตอนนี้ในระบบ
- 🟢 เตรียมเครื่องมือ ← กำลังทำช่วงนี้
- ⚪ Angular (หน้าบ้าน) (ยังไม่ถึง)
- 🟢 NestJS (หลังบ้าน) ← กำลังทำช่วงนี้
- ⚪ PostgreSQL (ฐานข้อมูล) (ยังไม่ถึง)
ต่อไป: ฝึกภาษา TypeScript ที่จะใช้เขียนหลังบ้าน
2.1 สร้างโครงโปรเจกต์
cd C:\
mkdir webdev
cd webdev
mkdir booklab
cd booklab
npm init -y
💡
npm init -y= สร้างไฟล์package.jsonเปล่า ๆ ให้อัตโนมัติ (ตัว-yคือตอบ "ใช่" ทุกคำถามแทนเรา) ไฟล์นี้คือบัตรประจำตัวของโปรเจกต์ บอกว่าโปรเจกต์ชื่ออะไร ใช้เครื่องมืออะไรบ้าง
✅ ต้องเห็นไฟล์ package.json เปิดดูจะมีเนื้อหาประมาณนี้
{
"name": "booklab",
"version": "1.0.0",
...
}
2.2 ตั้งค่าให้เป็น monorepo
โปรเจกต์เราจะมีทั้งหลังบ้าน (NestJS) และหน้าบ้าน (Angular) อยู่ในที่เดียวกัน แบบนี้เรียกว่า monorepo (repo เดียว หลายโปรเจกต์ย่อยข้างใน)

เปิดไฟล์ package.json ด้วย VS Code (code . เปิดทั้งโฟลเดอร์ก็ได้) แล้วแก้ให้เป็นแบบนี้
{
"name": "booklab",
"version": "1.0.0",
"private": true,
"workspaces": ["apps/api", "apps/web"],
"scripts": {
"dev:api": "npm run start:dev --workspace api",
"dev:web": "npm start --workspace web",
"dev": "concurrently -n API,WEB -c blue,green \"npm run dev:api\" \"npm run dev:web\""
}
}
💡
workspaces= บอก npm ว่าในโฟลเดอร์นี้มีโปรเจกต์ย่อยอยู่ที่ไหนบ้าง ทำให้สั่งติดตั้งของทุกโปรเจกต์ย่อยได้ด้วยคำสั่งเดียวจาก root และแชร์node_modulesก้อนเดียวกันได้ ประหยัดพื้นที่และเวลา💡
private: true= กันเผลอเอาโปรเจกต์นี้ไป publish ขึ้น npm (ไม่มีผลอะไรกับเรา แต่เป็นธรรมเนียมที่ควรใส่)⚠️ ตอนนี้โฟลเดอร์
apps/apiและapps/webยังไม่มีอยู่จริง — ไม่เป็นไร npm จะข้ามไปเงียบ ๆ ถ้ายังไม่เจอ พอเราสร้างโฟลเดอร์จริงในขั้นต่อไปแล้วค่อยเชื่อมกันเอง
2.3 ติดตั้งเครื่องมือช่วยรันสองฝั่งพร้อมกัน
npm install --save-dev concurrently
💡
concurrently= เครื่องมือที่รันหลายคำสั่งพร้อมกันใน Terminal เดียว เราจะใช้ตอนอยากรันทั้งหลังบ้านและหน้าบ้านพร้อมกันด้วยคำสั่งnpm run dev(สร้างไว้ให้แล้วในขั้นที่แล้ว) แต่วันนี้ยังไม่ได้ใช้ เพราะมีแค่หลังบ้าน
✅ ต้องเห็น โฟลเดอร์ node_modules และไฟล์ package-lock.json เกิดขึ้น
2.4 สร้างโปรเจกต์ NestJS (หลังบ้าน)
mkdir apps
cd apps
npm exec -- @nestjs/cli@latest new api --package-manager npm --skip-git --skip-install
ระหว่างรอ (ใช้เวลาสักครู่) อ่านความหมายของคำสั่งนี้
💡
npm exec --= สั่งรันเครื่องมือโดยไม่ต้องติดตั้งค้างไว้ในเครื่องตลอดไป ถ้ามีติดตั้งอยู่ในโปรเจกต์แล้วจะใช้ตัวนั้นทันที ถ้ายังไม่มีจะดาวน์โหลดมาใช้ครั้งเดียวจบ เหมาะกับเครื่องมือที่ใช้แค่ตอนสร้างโปรเจกต์ครั้งแรก เครื่องหมาย--คือตัวแบ่งระหว่าง "คำสั่งของ npm เอง" กับ "คำสั่งที่จะให้รันจริง" ต้องมีเว้นวรรคล้อมทั้งสองข้างเสมอ 💡@nestjs/cli= เครื่องมือสร้างโครงโปรเจกต์ NestJS ให้อัตโนมัติ ไม่ต้องมานั่งสร้างไฟล์เองทีละไฟล์ 💡--skip-git= ไม่ต้องสร้าง Git repo ให้ (วิชานี้ไม่ใช้ Git) 💡--skip-install= ยังไม่ต้องติดตั้ง package ตอนนี้ เดี๋ยวเราจะติดตั้งรวมทีเดียวจาก root ในขั้นถัดไป
✅ ต้องเห็น โฟลเดอร์ apps/api เกิดขึ้น มีไฟล์ src/main.ts, src/app.module.ts และอื่น ๆ
2.5 ติดตั้งทุกอย่างจาก root
กลับไปที่โฟลเดอร์บนสุดของโปรเจกต์
cd C:\webdev\booklab
npm install
ใช้เวลาสักครู่ (ยังไม่นานเท่าคาบหน้าที่จะมี Angular เพิ่มเข้ามาด้วย)
💡 ทำไมต้องกลับมา install ที่ root อีกรอบ ตอนสร้างโปรเจกต์ NestJS เราสั่ง
--skip-installไว้ พอมาสั่งnpm installที่ root ซึ่งรู้จักapps/apiผ่านworkspacesที่ตั้งไว้แล้ว มันจะติดตั้ง package ของapps/apiมารวมไว้ในnode_modulesที่ root เดียวกัน ทำให้ทุกโปรเจกต์ย่อยแชร์เครื่องมือชุดเดียวกันได้ ประหยัดพื้นที่กว่าแยกติดตั้งคนละที่มาก
✅ ต้องเห็น บรรทัดท้ายบอกจำนวน package ที่ติดตั้ง เช่น added 697 packages
2.6 เปิดใน VS Code
code .
💡 จุด
.แปลว่า "โฟลเดอร์ที่เรายืนอยู่ตอนนี้"
ดูแถบด้านซ้ายใน VS Code จะเห็นโครงสร้างแบบนี้
booklab/
├── apps/
│ └── api/ ← NestJS (หลังบ้าน) — คาบนี้ทำตรงนี้
├── node_modules/
├── package.json
└── package-lock.json
💡 หน้าบ้าน (frontend) กับ หลังบ้าน (backend) หน้าบ้าน คือส่วนที่ผู้ใช้เห็นและกดใช้งานได้โดยตรง (Angular ที่รันอยู่ในเบราว์เซอร์ — จะสร้างในคาบที่ 3) หลังบ้าน คือส่วนที่ทำงานจริงอยู่เบื้องหลัง เก็บและจัดการข้อมูล (NestJS ที่ต่อกับฐานข้อมูล) ผู้ใช้ไม่เห็นส่วนนี้เลย
สำคัญ: สองตัวนี้เป็นโปรแกรมคนละตัว รันแยกกัน คุยกันด้วยการส่งข้อความไปกลับเท่านั้น ผู้ใช้แตะต้องหลังบ้านโดยตรงไม่ได้เลย
2.7 รันหลังบ้านครั้งแรก
ใน VS Code กด Ctrl + ` เปิด Terminal แล้วพิมพ์
npm run dev:api
✅ ต้องเห็น
[Nest] LOG [NestApplication] Nest application successfully started
เปิดเบราว์เซอร์ที่ http://localhost:3000 ต้องเห็นคำว่า Hello World!
💡
localhost:3000แปลว่าอะไรlocalhost= เครื่องตัวเอง ไม่ได้ออกอินเทอร์เน็ตเลย3000= port หรือเลขช่องทางเข้า เครื่องเดียวรันโปรแกรมได้หลายตัว จึงต้องแยกช่องกัน หลังบ้านจองช่อง 3000 ส่วนหน้าบ้าน Angular จะใช้ช่อง 4200 ในคาบที่ 3
⚠️ ปล่อย Terminal นี้รันทิ้งไว้ตลอดคาบ ห้ามปิด ถ้าต้องพิมพ์คำสั่งอื่น กดเครื่องหมาย
+เปิดอันใหม่
ช่วงที่ 3 — TypeScript เท่าที่ต้องใช้ (25 นาที)
🗺️ ตำแหน่งตอนนี้ในระบบ
- ✅ เตรียมเครื่องมือ (ทำไปแล้ว)
- ⚪ Angular (หน้าบ้าน) (ยังไม่ถึง)
- 🟢 NestJS (หลังบ้าน) ← กำลังทำช่วงนี้
- ⚪ PostgreSQL (ฐานข้อมูล) (ยังไม่ถึง)
ต่อไป: เขียน API ตัวแรกด้วยความรู้ TypeScript ที่เพิ่งฝึก
💡 TypeScript คืออะไร คือ JavaScript ที่เพิ่มความสามารถหนึ่งอย่าง คือบอกล่วงหน้าได้ว่าตัวแปรแต่ละตัวเก็บข้อมูลชนิดไหน พอเผลอใส่ผิดชนิด จะขีดเส้นแดงเตือนตั้งแต่ตอนพิมพ์ ไม่ต้องรอให้พังตอนผู้ใช้กดใช้จริง
3.1 สร้างไฟล์ทดลอง
สร้างไฟล์ apps/api/src/playground.ts แล้วพิมพ์เอง (อย่าคัดลอก จะได้เห็นว่า VS Code เตือนตรงไหน)
let title: string = 'Clean Code';
let year: number = 2008;
let available: boolean = true;
💡
: stringคือป้ายบอกว่าช่องนี้ใส่ได้แต่ข้อความ ลองเปลี่ยนtitleเป็นตัวเลขดู แล้วสังเกตเส้นแดง ชนิดที่ใช้บ่อย:stringข้อความ,numberตัวเลข,booleanจริง/เท็จ
พิมพ์ต่อ
interface Book {
id: number;
title: string;
author: string;
year: number;
}
💡 interface คือแบบฟอร์มเปล่า กำหนดว่าหนังสือหนึ่งเล่มต้องมีช่องอะไรบ้าง ใครจะสร้างหนังสือต้องกรอกครบทั้งสี่ช่อง ขาดช่องเดียวไม่ผ่าน — ตัว interface เองไม่เก็บข้อมูล เป็นแค่กติกา
const books: Book[] = [
{ id: 1, title: 'Clean Code', author: 'Robert C. Martin', year: 2008 },
{ id: 2, title: 'The Pragmatic Programmer', author: 'Andy Hunt', year: 1999 },
];
console.log(books);
💡
Book[]วงเล็บเหลี่ยมแปลว่า "หลายอัน" — รายการที่มีหนังสือหลายเล่ม ทุกเล่มต้องกรอกตามแบบฟอร์มBook
3.2 ทดลองทำให้มันพัง
books.push({ id: 3, title: 'Refactoring' });
✅ ต้องเห็น เส้นหยักแดง บอกว่าขาด author กับ year
นี่คือประโยชน์หลักของ TypeScript — ถ้าเป็น JavaScript ธรรมดาบรรทัดนี้จะผ่านฉลุย แล้วไปพังตอนผู้ใช้จริงเปิดหน้าเว็บ ซึ่งกว่าจะรู้ก็สายไปแล้ว
ลบบรรทัดนี้ออกก่อนไปต่อ
3.3 งานที่ต้องรอ
async function getBooks(): Promise<Book[]> {
return books;
}
getBooks().then((result) => console.log('จำนวนหนังสือ:', result.length));
💡
async/Promise/awaitงานบางอย่างต้องรอ เช่นไปหยิบข้อมูลจากฐานข้อมูล เหมือนกดสั่งซื้อของออนไลน์แล้วต้องรอของมาส่งถึงก่อนถึงจะแกะดูได้
async= ป้ายบอกว่า "ฟังก์ชันนี้เป็นงานที่ต้องรอ"Promise<Book[]>= ใบจอง ยังไม่ใช่หนังสือจริง แต่สัญญาว่าเดี๋ยวจะได้รายการหนังสือแน่นอนawait= "หยุดตรงนี้ รอของมาถึงก่อน" (จะใช้เยอะในคาบหน้า)ทุกครั้งที่โค้ดคุยกับฐานข้อมูลหรือ API จะเจอสามคำนี้เสมอ
ช่วงที่ 4 — สร้าง API ตัวแรก (35 นาที)
🗺️ ตำแหน่งตอนนี้ในระบบ
- ✅ เตรียมเครื่องมือ (ทำไปแล้ว)
- ⚪ Angular (หน้าบ้าน) (ยังไม่ถึง)
- 🟢 NestJS (หลังบ้าน) ← กำลังทำช่วงนี้
- ⚪ PostgreSQL (ฐานข้อมูล) (ยังไม่ถึง)
ต่อไป: คาบหน้า: ต่อ API เข้ากับฐานข้อมูลจริง (PostgreSQL)
💡 API คืออะไร คือช่องทางกลางที่โปรแกรมหนึ่งเปิดไว้ให้อีกโปรแกรมหนึ่งมาขอข้อมูลหรือขอให้ทำงานบางอย่างแทน โดยไม่ต้องรู้เลยว่าเบื้องหลังมันทำงานอย่างไร หน้าเว็บ Angular แตะฐานข้อมูลตรง ๆ ไม่ได้ ต้องขอผ่านช่องทางนี้เท่านั้น เพราะโค้ดที่รันในเบราว์เซอร์ใครก็เปิดอ่านได้ ถ้าเอารหัสฐานข้อมูลไปไว้ตรงนั้น เท่ากับแปะรหัสให้คนทั้งโลกดู
💡 endpoint = URL เฉพาะจุดหนึ่งที่ตอบสนองคำขอเรื่องใดเรื่องหนึ่ง
/api/booksคือ endpoint ที่ตอบคำขอ "ขอรายชื่อหนังสือ"
4.1 เปิดใช้งาน CORS และตั้งให้ทุก endpoint ขึ้นต้นด้วย /api
เปิดไฟล์ apps/api/src/main.ts แก้ให้เป็นแบบนี้
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors();
app.setGlobalPrefix('api');
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
💡
app.enableCors()= เปิดใช้งาน CORS (Cross-Origin Resource Sharing) เพื่ออนุญาตให้หน้าบ้าน Angular (ที่รันบน port 4200) สามารถยิงคำขอ HTTP มาดึงข้อมูลจากหลังบ้าน NestJS (ที่รันบน port 3000) ได้โดยตรงโดยไม่ถูกเบราว์เซอร์บล็อก💡
app.setGlobalPrefix('api')= สั่งให้ NestJS เติมคำว่า/apiไว้หน้า URL ของทุก endpoint โดยอัตโนมัติ ไม่ต้องพิมพ์เองทุกจุด การรวม endpoint ไว้ใต้/apiช่วยให้แยกเส้นทางระหว่าง API กับหน้าบ้านได้อย่างชัดเจน
ดู Terminal ที่รัน npm run dev:api จะเห็นมันรีสตาร์ทตัวเองอัตโนมัติ แล้วลองเปิด http://localhost:3000/api/ ต้องเห็น Hello World! เหมือนเดิม (แค่ URL เปลี่ยนไปมี /api นำหน้า)
4.2 สร้างแผนกหนังสือ
เปิด Terminal ใหม่ (อย่าปิดตัวที่รันอยู่)
cd apps/api
npm exec -- nest g module books
npm exec -- nest g controller books --no-spec
💡 module = แผนก เก็บทุกอย่างเรื่องหนังสือไว้ด้วยกัน ไม่ปนแผนกอื่น 💡 controller = พนักงานต้อนรับของแผนก รับคำขอจากลูกค้าแล้วตอบกลับ 💡
nest g—gย่อจาก generate สั่งให้สร้างไฟล์โครงร่างให้อัตโนมัติ
✅ ต้องเห็น โฟลเดอร์ apps/api/src/books/ มีไฟล์ books.module.ts และ books.controller.ts
4.3 สร้างแบบฟอร์มหนังสือ
สร้างไฟล์ apps/api/src/books/book.interface.ts
export interface Book {
id: number;
title: string;
author: string;
year: number;
}
💡
export= เปิดให้ไฟล์อื่นเรียกใช้ได้ ถ้าไม่ใส่ ของจะอยู่แค่ในไฟล์ตัวเอง
4.4 เขียน controller
แทนที่ทั้งไฟล์ apps/api/src/books/books.controller.ts
import { Controller, Get } from '@nestjs/common';
import { Book } from './book.interface';
const BOOKS: Book[] = [
{ id: 1, title: 'Clean Code', author: 'Robert C. Martin', year: 2008 },
{ id: 2, title: 'The Pragmatic Programmer', author: 'Andy Hunt', year: 1999 },
{ id: 3, title: 'Refactoring', author: 'Martin Fowler', year: 1999 },
];
@Controller('books')
export class BooksController {
@Get()
findAll(): Book[] {
return BOOKS;
}
}
💡 เครื่องหมาย
@(decorator) = ป้ายที่แปะไว้บนหัว บอกว่าสิ่งนี้ทำหน้าที่อะไร
@Controller('books')= "ทุกคำขอที่ขึ้นต้นด้วย/booksมาหาฉัน" (แล้วรวมกับ/apiที่ตั้งไว้ในขั้นที่ 4.1 กลายเป็น/api/books)@Get()= "ฟังก์ชันนี้ตอบคนที่มาขอดูข้อมูล"💡
import= เรียกของจากไฟล์อื่นมาใช้ 💡: Book[]ท้ายชื่อฟังก์ชัน = สัญญาว่าจะคืนรายการหนังสือเท่านั้น
4.5 ทดสอบ
เปิดเบราว์เซอร์ที่ http://localhost:3000/api/books
✅ ต้องเห็นข้อมูลหนังสือ 3 เล่ม หน้าตาแบบนี้
[{"id":1,"title":"Clean Code","author":"Robert C. Martin","year":2008}, ...]
💡 JSON = รูปแบบการเขียนข้อมูลให้โปรแกรมส่งหากันรู้เรื่อง เขียนเป็นคู่ "ชื่อช่อง: ค่า" ในวงเล็บปีกกา หน้าตาเหมือน object ใน JavaScript
💡
GET= เวลาเราพิมพ์ URL ในเบราว์เซอร์ มันส่งคำขอชนิดGETแปลว่า "ขอดูข้อมูล" เสมอ ยังมีอีกสามชนิดคือPOSTเพิ่มใหม่,PUTแก้ไข,DELETEลบ — จะได้ใช้ครบในคาบที่ 5
❌ ถ้าขึ้น 404 → ดู Terminal ว่ามีข้อความสีแดงไหม แล้วเช็กว่า BooksModule ถูกเรียกใช้ใน app.module.ts แล้วหรือยัง
💡 404 = รหัสที่เซิร์ฟเวอร์ตอบว่า "ไม่เจอสิ่งที่ขอ" มักเกิดจากพิมพ์ URL ผิด หรือยังไม่ได้สร้าง endpoint นั้น
4.6 ทำเอง — เพิ่ม endpoint ที่สอง
ทำให้ http://localhost:3000/api/books/count ตอบกลับว่า
{ "total": 3 }
คำใบ้: ใช้ @Get('count') แล้วคืน object ธรรมดา
🚀 ถ้าเสร็จก่อนเพื่อน
- เพิ่ม endpoint
/api/books/newestคืนเฉพาะหนังสือปีใหม่ที่สุด - เพิ่มช่อง
publisherใน interfaceBookแล้วดูว่า TypeScript เตือนที่ไหนบ้าง - เปลี่ยน
@Get()เป็น@Post()แล้วเปิด URL เดิม — ทำไมหาไม่เจอ?
❓ ปัญหาที่พบบ่อย
| อาการ | สาเหตุ | วิธีแก้ |
|---|---|---|
'npm' is not recognized |
เปิด PowerShell ก่อนติดตั้ง Node เสร็จ | ปิดแล้วเปิดใหม่ |
node -v ขึ้น v22 |
ติดตั้งผิดเวอร์ชัน | ถอนแล้วติดตั้ง Node 24 LTS |
EADDRINUSE: port 3000 |
มี Terminal เก่ารันค้าง แย่งช่อง 3000 | ปิด Terminal เก่า หรือรีสตาร์ทเครื่อง |
| แก้โค้ดแล้วไม่เปลี่ยน | ลืมกดบันทึก | Ctrl + S แล้วดู Terminal ว่าโหลดใหม่ |
| เส้นแดงเต็มไปหมด | npm install ยังไม่เสร็จ |
รอให้เสร็จ แล้วปิด-เปิด VS Code |
📌 การบ้านก่อนคาบหน้า
ทบทวนวิชาฐานข้อมูล: primary key, foreign key, ความสัมพันธ์ one-to-many — คาบหน้าจะออกแบบตารางจริงบน PostgreSQL แล้วให้ API ดึงจากฐานข้อมูลจริงแทน array ที่เขียนไว้ในโค้ด
💡 สรุปสั้น ๆ
- primary key = ช่องที่ระบุตัวตนของแต่ละแถวแบบไม่ซ้ำกันเลยในตาราง เหมือนเลขบัตรประชาชน หนึ่งคนมีเลขเดียว ไม่มีใครซ้ำ ในคาบหน้าจะเจอเป็นช่อง
idที่ฐานข้อมูลแจกเลขให้เองอัตโนมัติ- foreign key = ช่องในตารางหนึ่งที่ไปชี้ถึง primary key ของอีกตาราง ใช้บอกว่าแถวนี้ "เป็นของ" หรือ "เกี่ยวข้องกับ" แถวไหนในอีกตาราง เช่น ช่อง
categoryIdในตารางหนังสือที่ชี้ไปหาidของตารางหมวดหมู่- ความสัมพันธ์ one-to-many = "หนึ่งต่อหลาย" คือของฝั่งหนึ่งมีได้แค่ 1 แต่โยงไปหาอีกฝั่งได้หลายรายการ เช่น หมวดหมู่ 1 หมวด มีหนังสืออยู่ในนั้นได้หลายเล่ม แต่หนังสือ 1 เล่มอยู่ได้แค่หมวดหมู่เดียว
ไม่ต้องเข้าใจลึกตอนนี้ก็ได้ คาบหน้าจะได้ลงมือสร้างตารางจริงแล้วจะเห็นภาพชัดขึ้นเยอะ