
กำลังโหลด...

กำลังโหลด...

โปรเจคพร้อมแล้ว ทีนี้ขอของจริง — Server ที่เปิดขึ้นมาแล้วเข้า localhost:3000 ได้
เอาแค่ตอบข้อความกลับมาก่อนก็พอ ยังไม่ต้องมีข้อมูลอะไร แต่พี่อยากให้น้อง พิมพ์เองทีละบรรทัด ไม่ก๊อป เพราะ 6 บรรทัดนี้จะใช้ไปตลอดทั้งคอร์ส
เป้าหมายของ Mission นี้: สร้าง Express Server ตัวแรกที่รันได้จริง และเข้าใจทุกบรรทัดว่า ทำอะไร
จบ Mission นี้คุณจะ
localhost:3000 ได้req และ res คืออะไรNode.js เปิดเซิร์ฟเวอร์เองได้อยู่แล้ว แต่โค้ดจะยาวและต้องจัดการเองทุกอย่าง
// Node.js เพียวๆ — ต้องแยก URL กับ Method เองด้วย if
import http from "node:http";
const server = http.createServer((req, res) => {
if (req.url === "/books" && req.method === "GET") {
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify([{ id: 1 }]));
} else if (req.url === "/books" && req.method === "POST") {
// ...ต่อไปเรื่อยๆ กลายเป็น if ยาวเป็นหางว่าว
}
});
Express คือ library ที่มาช่วยจัดระเบียบตรงนี้ ให้เขียนสั้นและอ่านง่ายขึ้นมาก
app.get("/books", (req, res) => res.json([{ id: 1 }]));
app.post("/books", (req, res) => res.status(201).json({ id: 2 }));
เทียบกับร้านอาหาร: Node.js คือ ตัวร้าน ส่วน Express คือ พนักงานต้อนรับ ที่คอยรับออเดอร์ แล้วส่งต่อให้ถูกเชฟ — ไม่มีพนักงานต้อนรับก็เปิดร้านได้ แต่วุ่นวายมาก
flowchart TD
A["Browser ยิง GET /books"] --> B["Node.js รับที่ Port 3000"]
B --> C["Express ดู Method + Path"]
C --> D{"มี route ตรงกันไหม?"}
D -->|"ตรง"| E["รัน handler function<br/>(req, res) => ..."]
D -->|"ไม่ตรง"| F["ตอบ 404 อัตโนมัติ"]
E --> G["res.json(...) ส่งกลับ"]
G --> A
F --> A
style C fill:#3f2d5c,stroke:#a855f7,color:#fff
สร้างไฟล์ index.js ในโฟลเดอร์ books-api แล้วพิมพ์ตามทีละบรรทัด อย่าก๊อปทีเดียวจบ
// บรรทัดที่ 1
import express from "express";
ดึง Express ที่ npm install ไว้เข้ามาใช้ — เหมือน import { useState } from "react" ที่คุ้นเคย
// บรรทัดที่ 2
const app = express();
เรียกฟังก์ชัน express() เพื่อ สร้างแอปพลิเคชันขึ้นมา 1 ตัว ตัวแปร app นี้คือ "ร้าน" ของเรา
ทุกอย่างหลังจากนี้จะสั่งผ่าน app หมด
// บรรทัดที่ 3
const PORT = 3000;
Port คือ เลขช่องประตู ของเครื่อง — เครื่องหนึ่งเครื่องมีที่อยู่ (IP) เดียว แต่รันหลายโปรแกรม พร้อมกันได้ Port เลยเป็นตัวบอกว่า Request นี้จะเข้าประตูไหน
เครื่องของเรา (localhost)
+----------------------------------------+
| Port 3000 -> Express Server ของเรา |
| Port 5432 -> PostgreSQL (Backend Explorer 2) |
| Port 5500 -> Live Server ของ VS Code |
+----------------------------------------+
// บรรทัดที่ 4-6
app.get("/", (req, res) => {
res.send("Hello Backend!");
});
แยกทีละชิ้น
| ชิ้นส่วน | ความหมาย |
|---|---|
app.get |
ดักเฉพาะ Request ที่ใช้ Method GET |
"/" |
ดักเฉพาะ Path / (หน้าแรก) |
(req, res) => {...} |
Handler — ฟังก์ชันที่จะรันเมื่อมี Request ตรงเงื่อนไข |
req |
Request — ข้อมูลขาเข้า (ใครส่งมา ส่งอะไรมา) |
res |
Response — เครื่องมือสำหรับส่งคำตอบกลับ |
res.send(...) |
ส่งข้อความกลับไปหา Client |
จำง่ายๆ:
req= จดหมายที่เขาส่งมา (อ่านอย่างเดียว) /res= ปากกาที่เราใช้เขียนตอบกลับ
// บรรทัดที่ 7-9
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
app.listen() คือคำสั่ง "เปิดร้าน" — สั่งให้โปรแกรมยืนรอ Request ที่ Port 3000 ไปเรื่อยๆ
ไม่จบการทำงาน ฟังก์ชันข้างในจะรันครั้งเดียวตอนเปิดสำเร็จ
สำคัญมาก: app.listen() ต้องอยู่ บรรทัดล่างสุดเสมอ — เพราะ route ทั้งหมดต้องถูก
ลงทะเบียนก่อนเปิดร้าน
index.jsimport express from "express";
const app = express();
const PORT = 3000;
app.get("/", (req, res) => {
res.send("Hello Backend!");
});
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
รันเลย
node index.js
จะเห็นข้อความ Server running on http://localhost:3000 แล้วเคอร์เซอร์ค้าง ไม่กลับมา —
นี่คือเรื่องปกติ แปลว่าโปรแกรมกำลัง "ยืนรอ" อยู่ ไม่ใช่ค้าง
เปิดเบราว์เซอร์ไปที่ http://localhost:3000 → เห็น Hello Backend!
🎉 นี่คือ Backend ตัวแรกของคุณ
res.send() vs res.json()res.send("Hello"); // ส่งข้อความธรรมดา (Content-Type: text/html)
res.json({ message: "Hello" }); // ส่ง JSON (Content-Type: application/json)
res.status(201).json({ id: 1 }); // กำหนด Status Code แล้วส่ง JSON
ในการทำ API เราใช้ res.json() เกือบตลอด เพราะ
JSON.stringify เอง)Content-Type: application/json ให้ ทำให้ Frontend res.json() ฝั่งนั้นได้เลย| Error | สาเหตุ | วิธีแก้ |
|---|---|---|
EADDRINUSE: address already in use :::3000 |
มี Server ตัวเก่ารันค้างอยู่ที่ Port เดียวกัน | กด Ctrl + C ที่ terminal เก่า หรือเปลี่ยนไปใช้ Port 3001 |
Cannot GET /books ในเบราว์เซอร์ |
ยังไม่ได้เขียน app.get("/books", ...) หรือพิมพ์ path ผิด |
เช็กว่า path ตรงกันเป๊ะ (/book ≠ /books) |
| แก้โค้ดแล้วผลไม่เปลี่ยน | Node โหลดไฟล์แค่ตอนเริ่ม | Ctrl + C แล้ว node index.js ใหม่ (หรือใช้ nodemon ใน Mission 4) |
Cannot use import statement outside a module |
ลืม "type": "module" |
เพิ่มใน package.json |
เขียน route ไว้ ใต้ app.listen() |
Route ถูกลงทะเบียนไม่ทัน | ย้าย app.listen() ไปบรรทัดล่างสุดเสมอ |
ลืม res.send()/res.json() ใน handler |
Express ไม่ตอบอะไรเลย | เบราว์เซอร์จะหมุนค้างจนหมดเวลา — ทุก handler ต้องจบด้วยการส่ง response |
express() สร้างแอป → app.get(path, handler) ลงทะเบียนเส้นทาง → app.listen(port) เปิดร้านreq = ข้อมูลขาเข้า / res = เครื่องมือส่งคำตอบres.json() และอย่าลืมว่า ทุก handler ต้องส่ง response เสมอ
Workshop — เปิด Server ตัวแรก
สร้าง index.js แล้วเขียน Server ที่ตอบ Hello Backend! ที่ path /
รันด้วย node index.js แล้วเปิด http://localhost:3000 ให้เห็นข้อความ
เพิ่ม route อีก 3 เส้นด้วยตัวเอง
| Path | ต้องตอบกลับว่า |
|---|---|
/about |
ข้อความ "Books API v1.0" |
/health |
JSON: { "status": "ok" } |
/time |
JSON ที่มีเวลาปัจจุบัน เช่น { "now": "2026-08-06T..." } |
ลองเข้า http://localhost:3000/abcdef ที่ไม่มี route รองรับ — เกิดอะไรขึ้น?
เปิด DevTools → Network ดู Status Code ว่าได้เลขอะไร แล้วจดไว้

ข้อ 1. app.listen(3000) ทำหน้าที่อะไร
ข้อ 2. ใน (req, res) => {} ตัว res คืออะไร
ข้อ 3. Error EADDRINUSE เกิดจากอะไร
ข้อ 4. res.json({a: 1}) ต่างจาก res.send('{a: 1}') อย่างไร
ข้อ 5. ถ้าเขียน route ไว้ใต้ app.listen() จะเกิดอะไรขึ้น
ข้อ 6. ทำไมเปิด Server แล้ว terminal ถึงค้าง ไม่กลับมาที่ prompt