Saltar al contenido

Middleware

Puedes añadir middleware a las aplicaciones FastAPI.

Un "middleware" es una función que trabaja con cada request antes de que sea procesada por cualquier operación de path específica. Y también con cada response antes de retornarla.

  • Toma cada request que llega a tu aplicación.
  • Luego puede hacer algo con esa request o ejecutar cualquier código necesario.
  • Luego pasa la request para que sea procesada por el resto de la aplicación (por alguna operación de path).
  • Luego toma la response generada por la aplicación (por alguna operación de path).
  • Puede hacer algo con esa response o ejecutar cualquier código necesario.
  • Luego retorna la response.

Detalles Técnicos

Si tienes dependencias con yield, el código de salida se ejecutará después del middleware.

Si había alguna tarea en segundo plano (cubierto en la sección Tareas en Segundo Plano, lo verás más adelante), se ejecutarán después de todos los middlewares.

Crear un middleware

Para crear un middleware usas el decorador @app.middleware("http") sobre una función.

La función middleware recibe:

  • La request.
  • A function call_next that will receive the request as a parameter.
    • Esta función pasará la request a la operación de path correspondiente.
    • Luego retorna la response generada por la operación de path correspondiente.
  • Luego puedes modificar aún más la response antes de retornarla.
import time

from fastapi import FastAPI, Request

app = FastAPI()


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

Consejo

Ten en cuenta que los headers propietarios personalizados se pueden añadir usando el prefijo X-.

Pero si tienes headers personalizados que quieres que un cliente en un navegador pueda ver, necesitas añadirlos a tus configuraciones CORS (CORS (Cross-Origin Resource Sharing)) usando el parámetro expose_headers documentado en la documentación de CORS de Starlette.

Detalles Técnicos

También podrías usar from starlette.requests import Request.

FastAPI lo proporciona como una comodidad para ti, el desarrollador. Pero viene directamente de Starlette.

Antes y después de la response

Puedes añadir código para que se ejecute con la request, antes de que cualquier operación de path la reciba.

Y también después de que la response sea generada, antes de retornarla.

Por ejemplo, podrías añadir un header personalizado X-Process-Time conteniendo el tiempo en segundos que tomó procesar la request y generar una response:

import time

from fastapi import FastAPI, Request

app = FastAPI()


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

Consejo

Aquí usamos time.perf_counter() en lugar de time.time() porque puede ser más preciso para estos casos de uso. 🤓

Orden de ejecución de múltiples middlewares

Cuando añades múltiples middlewares usando ya sea el decorador @app.middleware() o el método app.add_middleware(), cada nuevo middleware envuelve la aplicación, formando una pila. El último middleware añadido es el más externo, y el primero es el más interno.

En el camino de la request, el middleware más externo se ejecuta primero.

En el camino de la response, se ejecuta último.

Por ejemplo:

app.add_middleware(MiddlewareA)
app.add_middleware(MiddlewareB)

Esto resulta en el siguiente orden de ejecución:

  • Request: MiddlewareB → MiddlewareA → route

  • Response: route → MiddlewareA → MiddlewareB

Este comportamiento de apilamiento asegura que los middlewares se ejecuten en un orden predecible y controlable.

Otros middlewares

Puedes leer más sobre otros middlewares más adelante en la Guía de Usuario Avanzada: Middlewares Avanzados.

Leerás sobre cómo manejar CORS con un middleware en la siguiente sección.