Explore all courses in this category.
Explore all courses in this category.
Nguyễn Đình Cường
0 comment
09 Nov, 2026
Express là framework web tối giản nhất của Node.js, và toàn bộ sức mạnh của nó nằm ở middleware. Khi bạn hiểu middleware chạy thế nào và lỗi chảy ra sao, việc xây một API gọn gàng, dễ bảo trì không còn khó.
Middleware là hàm nhận (req, res, next). Nó có thể đọc hoặc sửa request, kết thúc request bằng cách trả lời, hoặc gọi next() để chuyển sang hàm tiếp theo. Các hàm chạy theo đúng thứ tự bạn khai báo.
const express = require('express');const app = express();app.use(express.json()); // đọc body JSONapp.use((req, res, next) => { console.log(req.method, req.url); next();});app.get('/health', (req, res) => res.json({ ok: true }));Thứ tự rất quan trọng. Nếu đặt express.json() sau route, body sẽ không được đọc. Quên gọi next() hoặc quên trả lời khiến request treo mãi.
function requireAuth(req, res, next) { const header = req.get('Authorization') || ''; const token = header.replace('Bearer ', ''); if (!token) { return res.status(401).json({ error: 'Chưa đăng nhập' }); } req.user = verifyToken(token); // giả sử hàm này tự viết next();}app.get('/profile', requireAuth, (req, res) => res.json(req.user));Gắn middleware vào từng route hoặc cả nhóm bằng express.Router() giúp bạn áp dụng quy tắc đúng chỗ cần.
Express nhận ra middleware xử lý lỗi nhờ có đúng bốn tham số (err, req, res, next). Nó phải được khai báo sau tất cả route:
app.use((req, res) => { res.status(404).json({ error: 'Không tìm thấy' });});app.use((err, req, res, next) => { console.error(err); const status = err.status || 500; res.status(status).json({ error: status === 500 ? 'Lỗi hệ thống' : err.message, });});Chú ý không trả chi tiết lỗi nội bộ (stack trace, câu SQL) cho người dùng ở production; hãy ghi log đầy đủ ở server nhưng chỉ trả thông điệp ngắn gọn.
Với Express 4, lỗi ném ra trong hàm async không tự đến middleware xử lý lỗi, request có thể treo. Bạn cần bắt và chuyển tiếp bằng next(err), hoặc dùng một hàm bọc:
const wrap = (fn) => (req, res, next) => Promise.resolve(fn(req, res, next)).catch(next);app.get('/users/:id', wrap(async (req, res) => { const user = await db.findUser(req.params.id); if (!user) { const e = new Error('Người dùng không tồn tại'); e.status = 404; throw e; } res.json(user);}));Express 5 đã tự chuyển lỗi từ handler async sang middleware lỗi, nên hãy kiểm tra phiên bản bạn đang dùng để biết có cần hàm bọc hay không.
Đừng dồn mọi thứ vào một file. Một cách tổ chức phổ biến: thư mục routes định nghĩa đường dẫn, controllers xử lý request, services chứa nghiệp vụ, middlewares chứa các hàm dùng chung. Cách chia này giúp bạn kiểm thử từng phần và thay đổi mà ít ảnh hưởng chỗ khác.
Một API tốt trả lỗi theo cùng một định dạng để ứng dụng khách dễ xử lý. Bạn có thể tạo một lớp lỗi riêng và để middleware lỗi biến nó thành phản hồi thống nhất:
class HttpError extends Error { constructor(status, message, details) { super(message); this.status = status; this.details = details; }}app.use((err, req, res, next) => { const status = err.status || 500; res.status(status).json({ error: { message: status === 500 ? 'Lỗi hệ thống' : err.message, details: err.details }, });});Giờ ở bất kỳ đâu trong code, bạn chỉ cần throw new HttpError(422, 'Dữ liệu không hợp lệ', {...}) và định dạng phản hồi luôn đồng nhất. Đồng đội của bạn, cũng như người viết ứng dụng di động gọi tới API, sẽ biết trước cấu trúc lỗi để xử lý.
Hãy tự xây một API quản lý công việc nhỏ gồm bốn route: danh sách, tạo mới, cập nhật và xóa. Thêm middleware ghi log request, middleware kiểm tra token đơn giản và middleware lỗi tập trung. Sau đó cố tình gây lỗi ở nhiều chỗ (id không tồn tại, dữ liệu sai, lỗi không lường trước) để xem phản hồi có nhất quán không. Bài tập nhỏ này giúp bạn hiểu rõ đường đi của request và lỗi trong Express.
Middleware là xương sống của Express: mỗi hàm một việc nhỏ, ghép thành đường ống rõ ràng, và lỗi được gom về một chỗ. Hãy bắt đầu bằng việc thêm middleware lỗi tập trung cho API của bạn, đó là cải thiện nhỏ mang lại hiệu quả lớn.
Muốn học bài bản và có lộ trình rõ ràng? Bạn có thể xem các khóa học trên codebem.com.
Nguyễn Đình Cường
0 comment