Middleware & CORS
Middleware in FastAPI
Section titled “Middleware in FastAPI”In Express, app.use(fn) registers middleware that wraps every request. FastAPI has the same concept: @app.middleware("http") decorates an async function that receives the request and a call_next callable. call_next invokes the next layer — exactly like calling next() in Express.
// Express middlewareapp.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();});# FastAPI middlewareimport timefrom 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 responseAdding custom headers
Section titled “Adding custom headers”A common middleware use-case is injecting headers into every response — for request tracing, caching hints, or security policies.
// Express — add header in middlewareapp.use((req, res, next) => { res.setHeader('X-Request-Id', crypto.randomUUID()); next();});# FastAPI — mutate response in middlewareimport uuidfrom 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 responseCross-Origin Resource Sharing (CORS) is configured via CORSMiddleware — FastAPI’s equivalent of the cors npm package used in Express or @nestjs/platform-express CORS option in NestJS.
// Expressimport cors from 'cors';app.use(cors({ origin: ['https://myapp.com', 'http://localhost:3000'], methods: ['GET', 'POST', 'PUT', 'DELETE'], allowedHeaders: ['Content-Type', 'Authorization'], credentials: true,}));
// NestJSapp.enableCors({ origin: ['https://myapp.com'], credentials: true,});# FastAPI — CORSMiddlewarefrom fastapi import FastAPIfrom 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=["*"],)Starlette middleware (class-based)
Section titled “Starlette middleware (class-based)”For reusable middleware you can also use Starlette’s class-based BaseHTTPMiddleware — similar to NestJS NestMiddleware with a use() method.
// NestJS class middleware@Injectable()export class LoggerMiddleware implements NestMiddleware { use(req: Request, res: Response, next: NextFunction) { console.log('Request...', req.method, req.url); next(); }}# FastAPI — Starlette BaseHTTPMiddlewarefrom starlette.middleware.base import BaseHTTPMiddlewarefrom starlette.requests import Requestfrom 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)Run this locally — needs FastAPI + a server. Playground is skipped: middleware requires the ASGI request lifecycle and cannot be demonstrated with a plain Python script.