Express.js, Routing, GET/POST và Middleware
- 24-07-2026
- Toanngo92
- 0 Comments
Express.js là framework Web tối giản chạy trên Node.js. Nó không thay thế Node.js mà bổ sung một lớp API thuận tiện để khai báo tuyến đường, đọc dữ liệu từ yêu cầu, tạo phản hồi và tổ chức middleware. Trong bài này, chúng ta chuyển nội dung Session 6 của giáo trình thành một hướng dẫn thực hành hiện đại: từ cài đặt Express đến xử lý GET, POST và viết middleware.

Mục lục
1. Express.js là gì?
Khi chỉ dùng module http của Node.js, lập trình viên phải tự kiểm tra URL, phương thức HTTP, header, body và tự chọn hàm xử lý phù hợp. Express gom các thao tác lặp lại này thành API ngắn gọn. Một ứng dụng Express về bản chất là chuỗi hàm nhận request, tạo response và chuyển quyền xử lý cho nhau.
Express phù hợp với nhiều loại ứng dụng: website render HTML, REST API, backend cho ứng dụng di động, dịch vụ nội bộ hoặc một lớp gateway nhỏ. Framework có thiết kế “không áp đặt”: bạn tự chọn cách tổ chức thư mục, cơ sở dữ liệu, thư viện xác thực và công cụ render giao diện.
Vì sao nên dùng Express?
- Routing rõ ràng: ánh xạ một URL và phương thức HTTP đến đúng hàm xử lý.
- API request/response tiện dụng: đọc tham số, query string, body và gửi HTML hoặc JSON dễ dàng.
- Middleware linh hoạt: tái sử dụng logic ghi log, xác thực, kiểm tra dữ liệu và xử lý lỗi.
- Hệ sinh thái lớn: dễ kết hợp với template engine, cơ sở dữ liệu và các gói npm.
- Dễ học: chỉ cần nắm JavaScript, Node.js và kiến thức HTTP căn bản.
2. Luồng xử lý của Express.js
Một yêu cầu thường đi qua các thành phần theo thứ tự: server nhận kết nối, router tìm tuyến phù hợp, middleware xử lý tác vụ chung, route handler tạo dữ liệu và cuối cùng Express gửi HTML, JSON hoặc tệp tĩnh về trình duyệt.

Router so khớp phương thức và đường dẫn. Chẳng hạn, GET /students và POST /students cùng đường dẫn nhưng là hai hành động khác nhau. Middleware có thể đọc hoặc bổ sung dữ liệu vào req, thay đổi res, kết thúc chu kỳ request-response, hoặc gọi next() để chuyển sang hàm tiếp theo. Handler là nơi thực hiện nghiệp vụ chính.
3. Cài đặt Express
Express hiện yêu cầu Node.js 18 trở lên. Tạo dự án mới và cài framework bằng npm:
mkdir express-bai-6
cd express-bai-6
npm init -y
npm install express
Tạo tệp app.js:
const express = require('express');
const app = express();
const PORT = 3000;
app.get('/', (req, res) => {
res.send('<h1>Xin chào Express.js!</h1>');
});
app.listen(PORT, () => {
console.log(`Server chạy tại http://localhost:${PORT}`);
});
Chạy node app.js, sau đó mở http://localhost:3000. express() tạo ứng dụng; app.get() khai báo route GET; app.listen() mở cổng và chờ kết nối.
4. Request và Response
Mỗi route handler thường nhận ba đối số: req, res và tùy trường hợp là next. req mô tả yêu cầu đến; res giúp xây dựng phản hồi.
Một số thuộc tính thường dùng của req
req.params: tham số nằm trong đường dẫn, ví dụ/students/:id.req.query: tham số query string, ví dụ?page=2.req.body: dữ liệu gửi trong body sau khi đã qua middleware phân tích.req.method,req.path,req.headers: phương thức, đường dẫn và header.
Một số phương thức thường dùng của res
res.send(): gửi chuỗi, HTML hoặc dữ liệu phù hợp.res.json(): gửi JSON và đặt content type tương ứng.res.status(): đặt mã trạng thái HTTP rồi nối tiếp vớisendhoặcjson.res.redirect(): chuyển hướng trình duyệt.res.sendFile(): gửi một tệp theo đường dẫn tuyệt đối.
app.get('/students/:id', (req, res) => {
res.status(200).json({
id: req.params.id,
detail: req.query.detail === 'true'
});
});
5. Routing với GET và POST
GET thường dùng để đọc tài nguyên và không nên làm thay đổi dữ liệu trên server. POST thường dùng để gửi dữ liệu mới. Một route gồm phương thức HTTP, đường dẫn và một hoặc nhiều handler.
app.get('/students', (req, res) => {
res.json([{ id: 1, name: 'Lan' }]);
});
app.post('/students', (req, res) => {
res.status(201).json({ message: 'Đã tạo sinh viên' });
});
6. Ví dụ xử lý form kết quả học tập
Giáo trình minh họa form nhập tên, điểm và trả về kết quả đạt hoặc chưa đạt. Bản cập nhật dưới đây dùng middleware tích hợp express.urlencoded(); không cần cài body-parser riêng cho form URL-encoded cơ bản.

Tạo thư mục public và tệp public/index.html:
<!doctype html>
<html lang="vi">
<head>
<meta charset="utf-8">
<title>Kết quả sinh viên</title>
</head>
<body>
<form action="/result" method="post">
<label>Tên sinh viên:
<input name="studentName" required>
</label>
<br>
<label>Điểm:
<input name="studentMark" type="number" min="0" max="100" required>
</label>
<br>
<button type="submit">Xem kết quả</button>
</form>
</body>
</html>
Cập nhật app.js:
const path = require('node:path');
const express = require('express');
const app = express();
const PORT = 3000;
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
app.post('/result', (req, res) => {
const name = String(req.body.studentName || '').trim();
const mark = Number(req.body.studentMark);
if (!name || !Number.isFinite(mark) || mark < 0 || mark > 100) {
return res.status(400).send('Dữ liệu không hợp lệ');
}
const result = mark >= 60 ? 'Đạt' : 'Chưa đạt';
res.send(`<h2>${name}: ${mark} điểm — ${result}</h2>`);
});
app.listen(PORT, () => {
console.log(`Server chạy tại http://localhost:${PORT}`);
});
Điểm quan trọng là phải kiểm tra dữ liệu từ người dùng. Không nên tin rằng req.body luôn chứa số hợp lệ. Khi code được dùng trong sản phẩm thật, cần escape dữ liệu trước khi ghép vào HTML hoặc ưu tiên render bằng template engine an toàn.
7. Middleware trong Express
Middleware là hàm có quyền truy cập req, res và next. Nếu middleware không kết thúc phản hồi bằng res.send(), res.json() hoặc phương thức tương tự, nó phải gọi next(). Nếu quên, yêu cầu sẽ bị treo.
let requestCount = 0;
app.use((req, res, next) => {
requestCount += 1;
console.log(`#${requestCount} ${req.method} ${req.originalUrl}`);
next();
});
app.get('/health', (req, res) => {
res.json({ ok: true, requestCount });
});

Thứ tự middleware rất quan trọng
Express chạy middleware theo thứ tự khai báo từ trên xuống. Middleware đọc body phải đứng trước route cần dùng req.body. Route 404 nên đứng sau tất cả route hợp lệ. Middleware xử lý lỗi có bốn tham số và thường đặt cuối cùng.
app.use((req, res) => {
res.status(404).json({ error: 'Không tìm thấy tài nguyên' });
});
app.use((err, req, res, next) => {
console.error(err);
res.status(500).json({ error: 'Lỗi máy chủ' });
});
8. Phục vụ tệp tĩnh
Để cung cấp CSS, JavaScript phía trình duyệt và hình ảnh trong thư mục public, dùng middleware tích hợp:
app.use(express.static('public'));
Sau đó tệp public/css/style.css có thể được truy cập bằng URL /css/style.css. Trong dự án lớn, nên dùng đường dẫn tuyệt đối để không phụ thuộc thư mục khởi chạy:
app.use(express.static(path.join(__dirname, 'public')));
9. Gợi ý cấu trúc dự án
express-bai-6/
├─ app.js
├─ package.json
├─ public/
│ ├─ index.html
│ └─ css/style.css
├─ routes/
├─ controllers/
└─ middleware/
Với ví dụ nhỏ, một tệp app.js là đủ. Khi ứng dụng lớn hơn, tách route, controller và middleware giúp code dễ kiểm thử và bảo trì. Không nên tách quá sớm thành quá nhiều tệp khi nghiệp vụ còn đơn giản.
10. Lỗi thường gặp
- Cannot find module ‘express’: chạy
npm install expressđúng thư mục cópackage.json. - req.body là undefined: thêm
express.json()hoặcexpress.urlencoded()trước route. - Yêu cầu quay mãi: middleware quên gọi
next()và cũng không gửi phản hồi. - Cannot GET /…: chưa có route GET khớp với đường dẫn hoặc route được khai báo sau handler 404.
- EADDRINUSE: cổng đang được tiến trình khác sử dụng; dừng tiến trình đó hoặc đổi cổng.
11. Bài tập thực hành
- Tạo ứng dụng quản lý nhân viên gồm các trường mã, tên, chức vụ và phòng ban. Viết route GET hiển thị form và POST nhận dữ liệu.
- Viết middleware ghi thời gian, phương thức và URL của từng request.
- Thêm route
GET /api/employees/:idtrả về JSON và mã 404 khi không có nhân viên. - Thử gửi JSON bằng Postman hoặc curl đến
POST /api/employees, sau đó kiểm tra dữ liệu đầu vào.
Tổng kết
Express.js giúp biến các API HTTP cấp thấp của Node.js thành mô hình routing và middleware dễ tổ chức. Sau bài này, bạn đã biết cách cài Express, tạo server, sử dụng req/res, xử lý GET và POST, đọc body của form, phục vụ tệp tĩnh và xây dựng middleware. Đây là nền tảng để phát triển REST API và các ứng dụng Web Node.js hoàn chỉnh.
