- Updated skill documentation files to include structured metadata for better organization. - Enhanced bilingual descriptions and guidelines for clarity in both English and Vietnamese. - Refined sections on usage, best practices, and related skills to ensure consistency across all documentation. - Improved formatting and removed outdated references to streamline the documentation experience. - Added best practices checklists to relevant skills for better usability and adherence to standards.
284 lines
10 KiB
Markdown
284 lines
10 KiB
Markdown
# Các Pattern Middleware
|
|
|
|
Express middleware patterns and best practices for GoodGo microservices including middleware chain ordering, custom middleware creation, authentication, validation, logging, and error handling middleware.
|
|
> Các patterns và best practices về Express middleware cho GoodGo microservices bao gồm thứ tự middleware chain, tạo custom middleware, authentication, validation, logging, và error handling middleware.
|
|
|
|
## Tổng Quan
|
|
|
|
Middleware functions are the fundamental building blocks of Express.js applications. They provide a way to execute code, make changes to requests and responses, end the request-response cycle, and call the next middleware. This guide covers middleware patterns, ordering, common middleware implementations, and best practices for GoodGo microservices.
|
|
|
|
Middleware functions là các building blocks cơ bản của ứng dụng Express.js. Chúng cung cấp cách để thực thi code, thay đổi requests và responses, kết thúc request-response cycle, và gọi middleware tiếp theo. Hướng dẫn này bao gồm các middleware patterns, thứ tự, common middleware implementations, và best practices cho GoodGo microservices.
|
|
|
|
## Khi Nào Sử Dụng
|
|
|
|
Use middleware patterns when:
|
|
- Creating custom Express middleware
|
|
- Organizing middleware chains and ordering
|
|
- Implementing authentication/authorization middleware
|
|
- Creating request/response transformation middleware
|
|
- Handling cross-cutting concerns (logging, metrics, validation)
|
|
- Implementing async middleware patterns
|
|
- Testing middleware implementations
|
|
|
|
Sử dụng middleware patterns khi:
|
|
- Tạo custom Express middleware
|
|
- Tổ chức middleware chains và thứ tự
|
|
- Implement authentication/authorization middleware
|
|
- Tạo request/response transformation middleware
|
|
- Xử lý cross-cutting concerns (logging, metrics, validation)
|
|
- Implement async middleware patterns
|
|
- Testing middleware implementations
|
|
|
|
## Khái Niệm Chính
|
|
|
|
### Chữ Ký Function Middleware
|
|
|
|
Express middleware functions have a specific signature that receives request, response, and next function.
|
|
|
|
Express middleware functions có chữ ký cụ thể nhận request, response, và next function.
|
|
|
|
```typescript
|
|
(req: Request, res: Response, next: NextFunction) => void | Promise<void>
|
|
```
|
|
|
|
### Các Loại Middleware
|
|
|
|
1. **Application-level / Cấp Ứng Dụng**: Applied to all routes (`app.use()`)
|
|
2. **Router-level / Cấp Router**: Applied to specific routes (`router.use()`)
|
|
3. **Route-level / Cấp Route**: Applied to specific route handlers
|
|
|
|
### Thứ Tự Thực Thi Middleware
|
|
|
|
Middleware order is critical! Execution flows top-to-bottom in the order they are registered.
|
|
|
|
Thứ tự middleware rất quan trọng! Thực thi theo trình tự từ trên xuống dưới theo thứ tự đăng ký.
|
|
|
|
```
|
|
Request → Middleware 1 → Middleware 2 → ... → Route Handler → Response
|
|
```
|
|
|
|
## Patterns
|
|
|
|
### Thứ Tự Middleware Chain
|
|
|
|
Standard middleware order in GoodGo services ensures proper request processing flow.
|
|
|
|
Thứ tự middleware chuẩn trong GoodGo services đảm bảo luồng xử lý request đúng cách.
|
|
|
|
```typescript
|
|
// Bảo mật
|
|
app.use(helmet());
|
|
app.use(cors({ ... }));
|
|
|
|
// Giới hạn tốc độ
|
|
app.use('/api', rateLimitMiddleware);
|
|
|
|
// Correlation ID (sớm cho tracing)
|
|
app.use(correlationMiddleware());
|
|
|
|
// Phân tích body
|
|
app.use(express.json());
|
|
app.use(express.urlencoded({ extended: true }));
|
|
app.use(cookieParser());
|
|
|
|
// Ghi log request
|
|
app.use(loggerMiddleware);
|
|
|
|
// Metrics
|
|
app.use(metricsMiddleware);
|
|
|
|
// Routes
|
|
app.use(createRouter());
|
|
|
|
// Xử lý lỗi (LUÔN CUỐI CÙNG)
|
|
app.use(notFoundHandler);
|
|
app.use(errorHandler);
|
|
```
|
|
|
|
**Tham Khảo**: [`services/iam-service/src/main.ts`](../../../services/iam-service/src/main.ts)
|
|
|
|
### Pattern Correlation Middleware
|
|
|
|
Adds correlation ID for request tracing across services.
|
|
|
|
Thêm correlation ID để tracing requests qua các services.
|
|
|
|
```typescript
|
|
export const correlationMiddleware = () => {
|
|
return (req: Request, res: Response, next: NextFunction) => {
|
|
const correlationId = req.headers['x-correlation-id'] || generateId();
|
|
req.correlationId = correlationId;
|
|
res.setHeader('x-correlation-id', correlationId);
|
|
next();
|
|
};
|
|
};
|
|
```
|
|
|
|
**Tham Khảo**: [`services/iam-service/src/middlewares/correlation.middleware.ts`](../../../services/iam-service/src/middlewares/correlation.middleware.ts)
|
|
|
|
### Pattern Authentication Middleware
|
|
|
|
Verifies JWT tokens and attaches user information to request.
|
|
|
|
Xác minh JWT tokens và gắn thông tin người dùng vào request.
|
|
|
|
```typescript
|
|
export const authenticate = () => {
|
|
return async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const token = extractToken(req);
|
|
if (!token) {
|
|
return res.status(401).json({ error: 'Unauthorized' });
|
|
}
|
|
|
|
const payload = await jwtService.verify(token);
|
|
req.user = payload;
|
|
next();
|
|
} catch (error) {
|
|
return res.status(401).json({ error: 'Invalid token' });
|
|
}
|
|
};
|
|
};
|
|
```
|
|
|
|
**Tham Khảo**: [`services/iam-service/src/middlewares/auth.middleware.ts`](../../../services/iam-service/src/middlewares/auth.middleware.ts)
|
|
|
|
### Pattern Validation Middleware
|
|
|
|
Validates request data using Zod schemas.
|
|
|
|
Validate dữ liệu request sử dụng Zod schemas.
|
|
|
|
```typescript
|
|
export const validateDto = (schema: AnyZodObject, property: 'body' | 'query' | 'params' = 'body') => {
|
|
return (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const validatedData = schema.parse(req[property]);
|
|
(req as any)[property] = validatedData;
|
|
next();
|
|
} catch (error) {
|
|
if (error instanceof ZodError) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
error: {
|
|
code: 'VALIDATION_ERROR',
|
|
details: error.errors,
|
|
},
|
|
});
|
|
}
|
|
next(error);
|
|
}
|
|
};
|
|
};
|
|
```
|
|
|
|
**Tham Khảo**: [`services/iam-service/src/middlewares/validation.middleware.ts`](../../../services/iam-service/src/middlewares/validation.middleware.ts)
|
|
|
|
### Pattern Async Middleware
|
|
|
|
Handle async operations properly to catch promise rejections.
|
|
|
|
Xử lý async operations đúng cách để catch promise rejections.
|
|
|
|
```typescript
|
|
export const asyncHandler = (fn: Function) => {
|
|
return (req: Request, res: Response, next: NextFunction) => {
|
|
Promise.resolve(fn(req, res, next)).catch(next);
|
|
};
|
|
};
|
|
|
|
// Usage
|
|
app.get('/users', asyncHandler(async (req, res) => {
|
|
const users = await userService.findAll();
|
|
res.json({ success: true, data: users });
|
|
}));
|
|
```
|
|
|
|
### Chuyển Đổi Request/Response
|
|
|
|
Transform request or response data in middleware.
|
|
|
|
Chuyển đổi dữ liệu request hoặc response trong middleware.
|
|
|
|
```typescript
|
|
export const transformResponse = () => {
|
|
return (req: Request, res: Response, next: NextFunction) => {
|
|
const originalJson = res.json.bind(res);
|
|
|
|
res.json = function(data: any) {
|
|
const transformed = {
|
|
success: true,
|
|
data,
|
|
timestamp: new Date().toISOString(),
|
|
};
|
|
return originalJson(transformed);
|
|
};
|
|
|
|
next();
|
|
};
|
|
};
|
|
```
|
|
|
|
## Thực Hành Tốt Nhất
|
|
|
|
1. **Order Matters / Thứ Tự Quan Trọng**: Đặt middleware đúng thứ tự (security → correlation → parsing → logging → routes → errors)
|
|
2. **Error Handling / Xử Lý Lỗi**: Luôn xử lý errors và gọi `next(error)` cho error middleware
|
|
3. **Async Support / Hỗ Trợ Async**: Wrap async middleware đúng cách để catch promise rejections
|
|
4. **Early Returns / Return Sớm**: Sử dụng early returns cho validation failures (không gọi `next()`)
|
|
5. **Request Extension / Mở Rộng Request**: Sử dụng TypeScript declaration merging để mở rộng Request type
|
|
6. **Conditional Logic / Logic Có Điều Kiện**: Sử dụng middleware factories cho conditional middleware
|
|
7. **Reusability / Tái Sử Dụng**: Tạo reusable middleware functions
|
|
8. **Performance / Hiệu Suất**: Giữ middleware lightweight, tránh heavy operations
|
|
|
|
## Lỗi Thường Gặp
|
|
|
|
1. **Wrong Order / Thứ Tự Sai**: Đặt middleware sai thứ tự (ví dụ: error handler trước routes)
|
|
2. **Not Calling Next / Không Gọi Next**: Quên gọi `next()` hoặc `next(error)`
|
|
3. **Async Errors / Lỗi Async**: Không xử lý promise rejections trong async middleware
|
|
4. **Early Return Issues / Vấn Đề Return Sớm**: Gọi `next()` sau khi đã send response
|
|
5. **Type Safety / An Toàn Kiểu**: Không mở rộng Express Request type đúng cách
|
|
6. **Performance / Hiệu Suất**: Thực hiện heavy operations trong middleware
|
|
|
|
## Xử Lý Sự Cố
|
|
|
|
### Middleware Không Thực Thi
|
|
|
|
**Problem / Vấn Đề**: Middleware không được gọi
|
|
|
|
**Solution / Giải Pháp**:
|
|
- Kiểm tra thứ tự middleware, đảm bảo nó được thêm trước routes
|
|
- Verify `next()` được gọi
|
|
- Check middleware registration order
|
|
|
|
### Lỗi Async Không Được Bắt
|
|
|
|
**Problem / Vấn Đề**: Unhandled promise rejections trong async middleware
|
|
|
|
**Solution / Giải Pháp**:
|
|
- Sử dụng `asyncHandler` wrapper
|
|
- Hoặc wrap async code trong try-catch với `next(error)`
|
|
|
|
**Example / Ví Dụ**:
|
|
```typescript
|
|
// ❌ Bad: Unhandled promise rejection
|
|
app.get('/users', async (req, res) => {
|
|
const users = await userService.findAll(); // Error not caught!
|
|
res.json(users);
|
|
});
|
|
|
|
// ✅ Good: Proper error handling
|
|
app.get('/users', asyncHandler(async (req, res) => {
|
|
const users = await userService.findAll();
|
|
res.json(users);
|
|
}));
|
|
```
|
|
|
|
## Tài Nguyên
|
|
|
|
- [Correlation Middleware](../../../services/iam-service/src/middlewares/correlation.middleware.ts) - Correlation ID implementation
|
|
- [Auth Middleware](../../../services/iam-service/src/middlewares/auth.middleware.ts) - Authentication middleware
|
|
- [Validation Middleware](../../../services/iam-service/src/middlewares/validation.middleware.ts) - Request validation
|
|
- [Error Middleware](../../../services/iam-service/src/middlewares/error.middleware.ts) - Error handling
|
|
- [Metrics Middleware](../../../services/iam-service/src/middlewares/metrics.middleware.ts) - Metrics collection
|
|
- [Error Handling](./error-handling-patterns.md) - Error middleware patterns
|