ข้ามไปยังเนื้อหา

Middleware และ CORS

ใน Express app.use(fn) ลงทะเบียน middleware ที่ wrap ทุก request FastAPI มีแนวคิดเดียวกัน: @app.middleware("http") ตกแต่ง async function ที่รับ request และ callable ชื่อ call_next ซึ่งเรียก layer ถัดไปเหมือนการเรียก next() ใน Express

TypeScript
// Express middleware
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
const ms = Date.now() - start;
console.log(`${req.method} ${req.url} ${res.statusCode} ${ms}ms`);
});
next();
});
Python
# FastAPI middleware
import time
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def log_requests(request: Request, call_next):
start = time.perf_counter()
response = await call_next(request)
ms = (time.perf_counter() - start) * 1000
print(f"{request.method} {request.url.path} "
f"{response.status_code} {ms:.1f}ms")
return response

Use case ที่พบบ่อยของ middleware คือการ inject headers ทุก response สำหรับ request tracing, caching hints หรือ security policies

TypeScript
// Express — เพิ่ม header ใน middleware
app.use((req, res, next) => {
res.setHeader('X-Request-Id', crypto.randomUUID());
next();
});
Python
# FastAPI — แก้ไข response ใน middleware
import uuid
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def add_request_id(request: Request, call_next):
response = await call_next(request)
response.headers["X-Request-Id"] = str(uuid.uuid4())
return response

Cross-Origin Resource Sharing (CORS) configure ผ่าน CORSMiddleware เทียบเท่ากับ cors npm package ใน Express หรือ CORS option ของ NestJS

TypeScript
// Express
import cors from 'cors';
app.use(cors({
origin: ['https://myapp.com', 'http://localhost:3000'],
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
}));
// NestJS
app.enableCors({
origin: ['https://myapp.com'],
credentials: true,
});
Python
# FastAPI — CORSMiddleware
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["https://myapp.com", "http://localhost:3000"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)

สำหรับ middleware ที่ใช้ซ้ำได้ คุณยังสามารถใช้ Starlette’s class-based BaseHTTPMiddleware คล้ายกับ NestJS NestMiddleware ที่มี use() method

TypeScript
// NestJS class middleware
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log('Request...', req.method, req.url);
next();
}
}
Python
# FastAPI — Starlette BaseHTTPMiddleware
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from fastapi import FastAPI
class LoggerMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
print(f"Request: {request.method} {request.url.path}")
response = await call_next(request)
print(f"Response: {response.status_code}")
return response
app = FastAPI()
app.add_middleware(LoggerMiddleware)

รันที่เครื่องตัวเอง — ต้องการ FastAPI + server Playground ข้ามในบทเรียนนี้: middleware ต้องการ ASGI request lifecycle และไม่สามารถ demonstrate ด้วย plain Python script

FastAPI equivalent ของ Express's next() function ภายใน middleware คืออะไร?
FastAPI middleware class ใดที่ใช้เปิดใช้งาน CORS?
จะลงทะเบียน middleware ใน FastAPI ได้อย่างไร?