0
0
FastapiHow-ToBeginner · 4 min read

How to Use Middleware in FastAPI: Simple Guide with Examples

In FastAPI, you use Middleware by creating a middleware class or function and adding it with app.add_middleware(). Middleware runs code before and after each request, letting you modify requests or responses globally.
📐

Syntax

To use middleware in FastAPI, you import Middleware and a middleware class like BaseHTTPMiddleware from starlette.middleware.base. Then you create a middleware class with a dispatch method that handles requests and responses. Finally, add it to your FastAPI app using app.add_middleware().

This lets you run code before the request reaches your route and after the response is created.

python
from fastapi import FastAPI, Request
from starlette.middleware.base import BaseHTTPMiddleware

class SimpleMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        # Code before request
        response = await call_next(request)
        # Code after response
        return response

app = FastAPI()
app.add_middleware(SimpleMiddleware)
💻

Example

This example shows a 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"] = "Middleware was here"
        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: Middleware was here
⚠️

Common Pitfalls

  • Not calling await call_next(request) inside dispatch will block the request and cause timeouts.
  • Modifying the request object directly is not recommended; instead, use headers or context.
  • Middleware order matters: the first added runs first on request and last on response.
  • Using synchronous code inside dispatch can block the server; always use async.
python
from fastapi import FastAPI, Request, Response
from starlette.middleware.base import BaseHTTPMiddleware

class WrongMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        # Missing await call_next(request) blocks the request
        print("This will block the request")
        return Response("Blocked", status_code=403)

app = FastAPI()
app.add_middleware(WrongMiddleware)  # This middleware will block all requests

# Correct way:
class RightMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        response = await call_next(request)
        return response
📊

Quick Reference

FastAPI Middleware Quick Tips:

  • Use BaseHTTPMiddleware to create middleware classes.
  • Always await call_next(request) to continue processing.
  • Middleware runs in the order added: first added runs first on request, last on response.
  • Use middleware for logging, headers, authentication, or modifying responses globally.

Key Takeaways

Add middleware in FastAPI using app.add_middleware() with a class inheriting BaseHTTPMiddleware.
Always await call_next(request) inside dispatch to pass control to the next handler.
Middleware runs code before and after each request, useful for logging, headers, or auth.
Avoid blocking code and modifying requests directly inside middleware.
Middleware order affects execution sequence on requests and responses.