บทที่ 1: พื้นฐาน Node.js และ Express Framework
สารบัญเนื้อหา
บทที่ 1: พื้นฐาน Node.js และ Express Framework
🎯 เป้าหมายการเรียนรู้
หลังจากเรียนบทนี้แล้ว คุณจะสามารถ:
- เข้าใจว่า Node.js คืออะไร และทำไมถึงเหมาะกับการพัฒนา Backend
- สร้าง REST API Server ด้วย Express Framework
- เข้าใจ Middleware Pattern และการใช้งาน
- จัดการ Environment Variables ด้วย dotenv
- ตั้งค่า CORS และ Security Headers
📚 ทฤษฎีและแนวคิด
Node.js คืออะไร?
Node.js คือ JavaScript Runtime ที่ทำงานนอก Browser โดยใช้ V8 Engine (เครื่องมือที่ Google Chrome ใช้รัน JavaScript) ทำให้เราสามารถเขียน JavaScript เพื่อสร้าง Backend Server ได้
ข้อดีของ Node.js:
- ✅ ใช้ JavaScript ทั้ง Frontend และ Backend (Full-stack JavaScript)
- ✅ Non-blocking I/O ทำงานได้เร็วและรองรับ Concurrent Requests ได้มาก
- ✅ มี NPM (Node Package Manager) ที่มี Library มากมาย
- ✅ เหมาะกับ Real-time Applications (Chat, Notifications)
Express Framework คืออะไร?
Express คือ Web Framework สำหรับ Node.js ที่ช่วยให้การสร้าง Web Server และ API ง่ายขึ้น
ฟีเจอร์หลัก:
- 🔹 Routing (จัดการ URL paths)
- 🔹 Middleware (ประมวลผล Request ก่อนถึง Route Handler)
- 🔹 Request/Response Handling
- 🔹 Template Engine Support
💻 โค้ดจริงจาก QUOM App
มาดูโค้ดจากไฟล์ backend/src/server.js กัน:
1. Import Dependencies (นำเข้า Libraries)
import express from "express";
import cors from "cors";
import morgan from "morgan";
import dotenv from "dotenv";
import path from "path";
import { fileURLToPath } from "url";
อธิบายแต่ละบรรทัด:
-
import express from "express"- นำเข้า Express Framework เพื่อสร้าง Web Server
-
import cors from "cors"- นำเข้า CORS (Cross-Origin Resource Sharing) เพื่อให้ Frontend จาก Domain อื่นเรียก API ได้
-
import morgan from "morgan"- นำเข้า Morgan สำหรับ Logging (บันทึก HTTP Requests)
-
import dotenv from "dotenv"- นำเข้า dotenv เพื่ออ่านค่าจากไฟล์
.env(Environment Variables)
- นำเข้า dotenv เพื่ออ่านค่าจากไฟล์
-
import path from "path"- นำเข้า path module สำหรับจัดการ file paths
-
import { fileURLToPath } from "url"- ใช้แปลง URL เป็น file path (จำเป็นใน ES Modules)
2. Load Environment Variables
dotenv.config();
คำอธิบาย:
- เรียกใช้
dotenv.config()เพื่อโหลดค่าจากไฟล์.envเข้าสู่process.env - ตัวอย่างไฟล์
.env:PORT=4010 MONGODB_URI=mongodb://localhost:27017/quom JWT_SECRET=your-secret-key
3. Connect to Database
import { connectDB } from "./config/db.js";
try {
await connectDB();
} catch (err) {
console.error("❌ DB Connection Failed:", err.message);
}
คำอธิบาย:
- เรียกฟังก์ชัน
connectDB()เพื่อเชื่อมต่อกับ MongoDB - ใช้
try-catchเพื่อจัดการ Error หากเชื่อมต่อไม่สำเร็จ awaitหมายความว่ารอให้การเชื่อมต่อเสร็จก่อนทำงานต่อ
4. Create Express Application
const app = express();
คำอธิบาย:
- สร้าง Express Application instance
appคือตัวแปรที่เราจะใช้ตั้งค่า Routes, Middleware ต่างๆ
5. Apply Middleware
5.1 Morgan Logger
app.use(morgan("dev"));
คำอธิบาย:
- ใช้ Morgan เพื่อ log HTTP requests ในรูปแบบ "dev"
- ตัวอย่าง output:
GET /api/notes 200 45.123 ms - 1234
5.2 JSON Body Parser
app.use(express.json({ limit: "2mb" }));
คำอธิบาย:
- แปลง Request Body ที่เป็น JSON ให้เป็น JavaScript Object
- กำหนด limit ที่ 2MB เพื่อป้องกัน Request ขนาดใหญ่เกินไป
- หลังจากใช้ middleware นี้ เราสามารถเข้าถึง
req.bodyได้
6. CORS Configuration (สำคัญมาก!)
const allowed = (process.env.CORS_ORIGIN || "")
.split(",")
.map(s => s.trim())
.filter(Boolean);
app.use(
cors({
origin: function (origin, cb) {
// Allow non-browser clients (curl, Postman) with no Origin
if (!origin) return cb(null, true);
// ✅ Allow any localhost port
const isLocalhost =
origin.startsWith("http://localhost:") ||
origin.startsWith("http://127.0.0.1:");
if (isLocalhost) return cb(null, true);
// ✅ Allow explicitly whitelisted origins from env
if (allowed.length === 0 || allowed.includes(origin))
return cb(null, true);
return cb(new Error("CORS blocked: " + origin));
},
credentials: true,
})
);
คำอธิบาย Step-by-Step:
-
อ่านค่า CORS_ORIGIN จาก .env
const allowed = (process.env.CORS_ORIGIN || "") .split(",") // แยกด้วย comma .map(s => s.trim()) // ตัด whitespace .filter(Boolean); // เอาค่าว่างออก -
Custom Origin Function
origin: URL ของ Frontend ที่ส่ง Request มาcb: Callback function เพื่อบอกว่าอนุญาตหรือไม่
-
กรณีที่อนุญาต:
- ไม่มี origin (เช่น Postman, curl)
- localhost ทุก port (สำหรับ Development)
- Origins ที่ระบุใน CORS_ORIGIN
-
credentials: true
- อนุญาตให้ส่ง Cookies และ Authorization Headers
7. Static Files Serving
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
app.use(
"/uploads",
express.static(path.join(__dirname, "..", process.env.UPLOAD_DIR || "uploads"))
);
คำอธิบาย:
fileURLToPath(import.meta.url): แปลง URL เป็น file pathpath.dirname(__filename): ได้ directory path ของไฟล์นี้express.static(): Serve static files (รูปภาพ, PDF, etc.)- เมื่อเข้า
http://localhost:4010/uploads/image.jpgจะได้ไฟล์จากโฟลเดอร์ uploads
8. Health Check Endpoint
app.get("/api/health", (req, res) =>
res.json({ ok: true, service: "QUOM API" })
);
app.get("/", (req, res) =>
res.send("QUOM Backend is running! 🚀<br>Port: " + (process.env.PORT || "Unknown"))
);
คำอธิบาย:
app.get(path, handler): กำหนด Route สำหรับ HTTP GETreq: Request object (ข้อมูลที่ Client ส่งมา)res: Response object (ใช้ส่งข้อมูลกลับ)res.json(): ส่ง JSON responseres.send(): ส่ง HTML/Text response
9. API Routes
import { authRouter } from "./routes/auth.js";
import { notesRouter } from "./routes/notes.js";
import { chatRouter } from "./routes/chat.js";
import { userRouter } from "./routes/user.js";
import { adminRouter } from "./routes/admin.js";
import { passwordResetRouter } from "./routes/password-reset.js";
app.use("/api/auth", authRouter);
app.use("/api/notes", notesRouter);
app.use("/api/chat", chatRouter);
app.use("/api/user", userRouter);
app.use("/api/admin", adminRouter);
app.use("/api/password-reset", passwordResetRouter);
คำอธิบาย:
- แยก Routes ออกเป็นไฟล์ต่างๆ เพื่อความเป็นระเบียบ
app.use(path, router): Mount router ที่ path ที่กำหนด- ตัวอย่าง: Request ไป
/api/auth/loginจะถูกจัดการโดยauthRouter
10. Error Handler Middleware
import { errorHandler } from "./middleware/errorHandler.js";
app.use(errorHandler);
คำอธิบาย:
- Error Handler ต้องอยู่ ท้ายสุด หลังจาก Routes ทั้งหมด
- จะจับ Errors ที่เกิดขึ้นจาก Routes และส่ง Response ที่เหมาะสม
11. Start Server
const port = process.env.PORT || 4010;
app.listen(port, () =>
console.log(`🚀 QUOM Backend running on :${port}`)
);
คำอธิบาย:
app.listen(port, callback): เริ่ม Server ที่ port ที่กำหนด- ใช้ port จาก Environment Variable หรือ 4010 เป็นค่า default
- Callback จะทำงานเมื่อ Server พร้อมรับ Requests
🔄 Flow Diagram: Request Lifecycle
Client Request
↓
CORS Middleware → ตรวจสอบ Origin
↓
Morgan Logger → บันทึก Request
↓
JSON Parser → แปลง Body เป็น Object
↓
Route Matching → หา Route ที่ตรงกับ URL
↓
Route Handler → ประมวลผล Request
↓
Send Response → ส่งข้อมูลกลับ Client
↓
Error Handler → จัดการ Error (ถ้ามี)
🎓 แนวคิดสำคัญ: Middleware Pattern
Middleware คืออะไร?
Middleware คือฟังก์ชันที่ทำงาน ระหว่าง Request และ Response
Signature:
function middleware(req, res, next) {
// ทำงานบางอย่าง
next(); // เรียก middleware ถัดไป
}
ตัวอย่าง Custom Middleware:
// Logger Middleware
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
// Authentication Middleware
app.use((req, res, next) => {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ error: "No token" });
}
// Verify token...
next();
});
📝 แบบฝึกหัด
คำถามทบทวน
- Node.js ใช้ Engine อะไรในการรัน JavaScript?
- Express Middleware ทำงานในลำดับใด?
- CORS ย่อมาจากอะไร และทำไมถึงสำคัญ?
app.use()และapp.get()ต่างกันอย่างไร?- ทำไม Error Handler ต้องอยู่ท้ายสุด?
โจทย์ปฏิบัติ
โจทย์ที่ 1: สร้าง Express Server ง่ายๆ
// TODO: สร้าง Express app
// TODO: เพิ่ม middleware สำหรับ JSON parsing
// TODO: สร้าง GET endpoint ที่ /api/hello ให้ return { message: "Hello World" }
// TODO: Start server ที่ port 3000
โจทย์ที่ 2: สร้าง Custom Logger Middleware
// TODO: สร้าง middleware ที่แสดง timestamp, method, และ url ของทุก request
// ตัวอย่าง output: [2026-01-20 15:00:00] GET /api/users
โจทย์ที่ 3: ตั้งค่า CORS
// TODO: อนุญาตเฉพาะ http://localhost:3000 และ https://myapp.com
📌 สรุป
ในบทนี้เราได้เรียนรู้:
✅ Node.js คือ JavaScript Runtime ที่ทำงานนอก Browser
✅ Express คือ Web Framework ที่ช่วยสร้าง API ได้ง่าย
✅ Middleware คือฟังก์ชันที่ประมวลผล Request ก่อนถึง Route Handler
✅ CORS สำคัญสำหรับการอนุญาตให้ Frontend เรียก API
✅ Environment Variables ช่วยแยกค่า configuration ออกจากโค้ด
ไฟล์ที่เกี่ยวข้อง
backend/src/server.js- Main server filebackend/package.json- Dependencies
🔜 บทถัดไป
บทที่ 2: MongoDB และ Mongoose Models
เราจะเรียนรู้การเชื่อมต่อ Database, สร้าง Schema, และทำ CRUD Operations