Skip to content

Middleware

You can add middleware to FastAPI applications.

A "middleware" is a function that works with every request before it is processed by any specific path operation. And also with every response before returning it.

  • It takes each request that comes to your application.
  • It can then do something to that request or run any needed code.
  • Then it passes the request to be processed by the rest of the application (by some path operation).
  • It then takes the response generated by the application (by some path operation).
  • It can do something to that response or run any needed code.
  • Then it returns the response.

Create a middleware

To create a middleware you use the decorator @app.middleware("http") on top of a function.

The middleware function receives:

  • The request.
  • A function call_next that will receive the request as a parameter.
    • This function will pass the request to the corresponding path operation.
    • Then it returns the response generated by the corresponding path operation.
  • You can then modify further the response before returning it.
import time

from fastapi import FastAPI
from starlette.requests import Request

app = FastAPI()


@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

Tip

This technique is used in the tutorial about SQL (Relational) Databases.

Tip

Have in mind that custom proprietary headers can be added using the 'X-' prefix.

But if you have custom headers that you want a client in a browser to be able to see, you need to add them to your CORS configurations, using the parameter expose_headers documented in Starlette's CORS docs.

Before and after the response

You can add code to be run with the request, before any path operation receives it.

And also after the response is generated, before returning it.

For example, you could add a custom header X-Process-Time containing the time in seconds that it took to process the request and generate a response:

import time

from fastapi import FastAPI
from starlette.requests import Request

app = FastAPI()


@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

Starlette's Middleware

You can also add any other Starlette Middleware.

These are classes instead of plain functions.

Including:

  • CORSMiddleware (described in the next section).
  • GZipMiddleware.
  • SentryMiddleware.
  • ...and others.