How to Create Custom Middleware in FastAPI Quickly
In FastAPI, create custom middleware by defining a class with an async
dispatch method that accepts request and call_next. Use await call_next(request) to process the request and modify the response before returning it. Then add your middleware class to the FastAPI app with add_middleware().Syntax
To create custom middleware in FastAPI, define a class with an async dispatch method that takes request and call_next as parameters. Inside, you can process the request, call the next handler with await call_next(request), and then modify or log the response before returning it.
Add the middleware to your FastAPI app using app.add_middleware(YourMiddlewareClass).
python
from fastapi import FastAPI, Request from starlette.middleware.base import BaseHTTPMiddleware class CustomMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next): # Code before request processing response = await call_next(request) # Code after response is generated return response app = FastAPI() app.add_middleware(CustomMiddleware)
Example
This example shows a custom middleware that logs the request method and URL before processing, and adds a custom header to the response.
python
from fastapi import FastAPI, Request from starlette.middleware.base import BaseHTTPMiddleware class LoggingMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next): print(f"Request: {request.method} {request.url}") response = await call_next(request) response.headers["X-Custom-Header"] = "CustomValue" return response app = FastAPI() app.add_middleware(LoggingMiddleware) @app.get("/") async def root(): return {"message": "Hello from FastAPI with middleware!"}
Output
Request: GET http://127.0.0.1:8000/
Response headers include: X-Custom-Header: CustomValue
Common Pitfalls
- Not awaiting
call_next(request)causes errors or no response. - Modifying the request object directly is not supported; use request state or headers carefully.
- For performance, avoid heavy processing inside middleware.
- Using middleware that blocks the event loop will slow down your app.
python
from fastapi import FastAPI, Request from starlette.middleware.base import BaseHTTPMiddleware # Wrong: forgetting to await call_next class WrongMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next): response = call_next(request) # Missing await return response # Right: always await call_next class RightMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next): response = await call_next(request) return response app = FastAPI() app.add_middleware(RightMiddleware)
Quick Reference
FastAPI Custom Middleware Cheat Sheet:
- Define a class inheriting from
BaseHTTPMiddleware. - Implement async
dispatch(self, request, call_next). - Use
await call_next(request)to get the response. - Modify or log request/response as needed.
- Add middleware with
app.add_middleware(YourMiddlewareClass).
Key Takeaways
Create custom middleware by subclassing BaseHTTPMiddleware and implementing async dispatch.
Always await call_next(request) to process the request and get the response.
Modify the response after call_next to add headers or logging.
Add middleware to FastAPI app with app.add_middleware().
Avoid blocking operations inside middleware to keep app responsive.