What is Middleware?

Middleware is software that sits between the server and your application logic, processing requests and responses. It handles cross-cutting concerns like authentication, logging, CORS, and error handling.

By Maciej Marzęta Updated 2025-02-01

Definition

Middleware is a layer of processing that sits between incoming HTTP requests and your application's route handlers. Each middleware function can inspect, modify, or reject a request before it reaches its handler, and similarly process the response before it's sent back to the client.

Middleware functions form a chain (often called a "pipeline") where each one calls the next. This design pattern enables clean separation of cross-cutting concerns like authentication, logging, and error handling.

Common Middleware Types

  • Authentication: Verify JWT tokens, API keys, or session cookies.
  • CORS: Handle Cross-Origin Resource Sharing headers.
  • Logging: Record request/response details for debugging and monitoring.
  • Rate limiting: Throttle requests to prevent abuse.
  • Compression: Gzip or Brotli compress responses.
  • Error handling: Catch exceptions and return formatted error responses.
  • Request ID: Assign unique IDs for distributed tracing.

Code Example

from fastapi import FastAPI, Request
from time import time
import logging

app = FastAPI()
logger = logging.getLogger(__name__)

@app.middleware("http")
async def log_requests(request: Request, call_next):
    start_time = time()
    
    # Process request
    response = await call_next(request)
    
    # Log after response
    duration = time() - start_time
    logger.info(
        f"{request.method} {request.url.path} "
        f"- {response.status_code} ({duration:.3f}s)"
    )
    
    response.headers["X-Process-Time"] = str(duration)
    return response

Frequently Asked Questions

What is the difference between middleware and dependency injection?

Middleware runs on every request (or a subset defined by path rules) and processes the entire request/response cycle. Dependency injection (in FastAPI) runs per-route and provides values to specific endpoint functions. Use middleware for global concerns; use dependencies for route-specific logic.

Need expert backend development?

I build scalable Python APIs and backend systems. Let's discuss your project.

Get in Touch