Middleware — runs before/after every request
Wrap the entire app. Each request passes through before reaching the route, response passes through after.
@app.middleware('http') — registers a middleware. Signature: async def(request, call_next). call_next(request) — runs the next middleware (or the route if you're last). Returns the response. Code BEFORE call_next runs on the way IN (request). Code AFTER call_next runs on the way OUT (response). ORDER: the LAST-added middleware runs FIRST on the request, LAST on the response (onion layers). Use cases: timing, security headers, CORS, GZip compression, logging, rate limiting, auth checks. CORS middleware is special — added with app.add_middleware(CORSMiddleware, ...) instead of the decorator. Middleware runs for EVERY request — keep it fast (no DB queries, no slow I/O).
-
Change the timing log to print only if elapsed > 100ms→ only log slow requests -
Add a new middleware that sets Cache-Control: no-store→ prevents browser caching -
Add a middleware that blocks requests with User-Agent containing 'bot'→ anti-bot -
Change X-Frame-Options from 'DENY' to 'SAMEORIGIN'→ allows framing from same domain