Middlewares de FastAPI

Un middleware es una función que se ejecuta antes y después de que cada solicitud llegue a la función de manejo de rutas.

Los middlewares pueden usarse para añadir registros (logs), modificar solicitudes/respuestas, manejar CORS y otra lógica común.


Cómo funciona el middleware

Flujo de ejecución del middleware:

  • La solicitud llega al middleware
  • El middleware ejecuta la lógica de preprocesamiento
  • El middleware pasa la solicitud al siguiente middleware o a la función de ruta
  • La función de ruta devuelve la respuesta
  • El middleware ejecuta la lógica de posprocesamiento
  • La respuesta se devuelve al cliente

Nombre Función
Cliente Navegadores, apps frontend, Postman, etc. envían solicitudes HTTP a FastAPI
Solicitud (Request) Objeto de solicitud HTTP, que contiene URL, cabeceras, cuerpo, cookies, etc.
Middleware 1 Primera capa de procesamiento después de que la solicitud entra
Middleware 2 Segunda capa de lógica de procesamiento
Middleware N Múltiples middlewares se ejecutan en orden
Función de manejo de ruta (Path Operation) El lugar donde realmente se ejecuta el código de negocio
Etapa de respuesta Después de que la ruta devuelve la Response, la respuesta pasa nuevamente por los middlewares
Los middlewares se devuelven en orden inverso La respuesta se devuelve en "orden inverso"
Response (respuesta) Datos que finalmente se devuelven al cliente

Crear middleware

Usar@app.middleware("http")Decorador para crear middleware:

Ejemplo

import time
from fastapi import FastAPI, Request

app = FastAPI()


@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    # 1. Procesamiento antes de la solicitud: registrar el tiempo de inicio
    start_time = time.time()

    # 2. Pasar la solicitud al siguiente middleware o función de ruta
    response = await call_next(request)

    # 3. Procesamiento después de la respuesta: calcular el tiempo de procesamiento y añadir cabeceras de respuesta
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response


@app.get("/")
async def root():
    return {"message": "Hello World"}

Explicación del código:

ParteDescripción
@app.middleware("http")Declara que esto es un middleware HTTP
request: RequestObjeto de solicitud actual
call_nextCallback que llama al siguiente middleware o función de ruta
await call_next(request)Pasa la solicitud a la siguiente capa y obtiene la respuesta

call_nextReciberequestel parámetro y devuelveresponse. Puedes, antes de llamarcall_nextmodificar la solicitud, y después de la llamada modificar la respuesta.


Middleware de registro de solicitudes

El siguiente middleware registra la información básica de cada solicitud:

Ejemplo

import time
import logging
from fastapi import FastAPI, Request

app = FastAPI()

logger = logging.getLogger("uvicorn.access")


@app.middleware("http")
async def log_requests(request: Request, call_next):
    # Registrar información de la solicitud
    logger.info(f"Solicitud: {request.method} {request.url}")

    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time

    # Registrar información de la respuesta
    logger.info(
        f"Respuesta: {request.method} {request.url} "
        f"Código de estado={response.status_code} Tiempo={process_time:.3f}s"
    )

    return response

Orden de ejecución de los middlewares

Los middlewares se ejecutan en el orden de registro; las solicitudes pasan por los middlewares en orden directo, y las respuestas en orden inverso:

请求 -> 中间件A(前) -> 中间件B(前) -> 路由函数
响应 <- 中间件A(后) <- 中间件B(后) <- 路由函数

El orden de registro de los middlewares es importante. Si tienes dos middlewares A y B, y registras A primero, la solicitud pasa primero por A y luego por B, pero la respuesta pasa primero por B y luego por A.


Usar middlewares integrados de Starlette

FastAPI hereda de Starlette y puede usar directamente los middlewares proporcionados por Starlette:

Ejemplo

from fastapi import FastAPI
from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware

app = FastAPI()

# Forzar redirección HTTPS
app.add_middleware(HTTPSRedirectMiddleware)


@app.get("/")
async def root():
    return {"message": "Acceso mediante HTTPS"}

Middlewares integrados comunes:

MiddlewareDescripción
HTTPSRedirectMiddlewareFuerza la redirección de solicitudes HTTP a HTTPS
TrustedHostMiddlewareLimita los nombres de host permitidos
GZipMiddlewareComprime automáticamente el contenido de la respuesta
CORSMiddlewareManeja solicitudes de dominios cruzados (se detalla en el próximo capítulo)

Middleware de compresión GZip

Habilitar la compresión GZip puede reducir el tamaño de la respuesta y aumentar la velocidad de transferencia:

Ejemplo

from fastapi import FastAPI
from fastapi.middleware.gzip import GZipMiddleware

app = FastAPI()

# Comprimir automáticamente cuando el tamaño de la respuesta supere los 1000 bytes
app.add_middleware(GZipMiddleware, minimum_size=1000)


@app.get("/")
async def root():
    return {"message": "Esta respuesta puede ser comprimida con GZip"}

Resumen

  • Los middlewares ejecutan lógica común en la cadena de procesamiento de solicitudes/respuestas
  • Usar@app.middleware("http")crear middleware personalizado
  • call_next(request)Pasar la solicitud a la siguiente capa
  • Los middlewares se ejecutan en orden de registro (solicitudes en orden directo, respuestas en orden inverso)
  • FastAPI/Starlette proporciona middlewares integrados como CORS, GZip, redirección HTTPS, etc.
Otras extensiones