Contenido del curso
Parámetros y Validación
CRUD en FastAPI
Arquitectura en FastAPI
Bases de Datos y Consultas
Middlewares
Unit Testing
Seguridad y Autenticación
Middlewares en FastAPI para medir requests
Resumen
Los middlewares en FastAPI son funciones de Python que se ejecutan justo antes y después de cada request, lo que te permite modificar el comportamiento global de tu API sin tocar cada endpoint. Si trabajas con FastAPI y necesitas validaciones, métricas o logs centralizados, dominar este patrón te ahorra horas de código repetido.
¿Qué es un middleware en FastAPI y para qué sirve?
Un middleware intercepta cada request entrante y cada response saliente. Es el lugar perfecto para aplicar lógica que debe correr en todas las rutas, sin duplicar código.
¿Qué es un middleware? Es una función que se ejecuta antes y después de cada request en tu API, ideal para validaciones globales, métricas y logs.
Un caso típico es el de CORS validations, un middleware que valida si el request proviene de un dominio aceptado por tu aplicación. FastAPI ya trae varios middlewares listos para usar, así que en proyectos reales lo más común es reutilizar los que ya existen en el paquete antes de escribir uno propio.
¿Cuándo conviene crear un custom middleware?
Cuando necesitas una lógica específica que ningún middleware preexistente cubre. En el ejemplo de la clase, construimos uno que mide cuánto tarda en procesarse cada request, una métrica útil para detectar endpoints lentos.
¿Cómo crear un middleware personalizado en FastAPI?
Dentro de tu archivo main.py, justo después de declarar la aplicación, defines una función asíncrona que recibe dos parámetros: el request actual y una función call_next que ejecuta el flujo por defecto.
La estructura mínima se ve así:
python import time from fastapi import Request
@app.middleware("http") async def log_request_time(request: Request, call_next): start_time = time.time() response = await call_next(request) process_time = time.time() - start_time print(f"Request {request.url} completed in {process_time:.4f} seconds") return response
Fíjate en tres detalles importantes:
- El decorador
@app.middleware("http")registra la función como middleware de tipo HTTP. await call_next(request)ejecuta el resto del pipeline y devuelve la respuesta.- Siempre debes retornar un
response, porque estás interceptando el ciclo completo del request.
Sin las líneas de start_time y process_time, este middleware sería transparente: dejaría pasar el request tal como llegó. La magia está en lo que agregas alrededor de call_next.
¿Cómo medir el tiempo de procesamiento de un request?
La lógica es directa. Guardas time.time() antes de llamar a call_next y vuelves a capturarlo después. La resta te da los segundos exactos que tardó el endpoint en responder.
¿Para qué sirve
call_nexten un middleware? Es la función que ejecuta el resto del pipeline del request. Sin ella, tu middleware bloquearía la respuesta.
Al ejecutar la app y llamar, por ejemplo, al endpoint de transactions con un límite de 50 y offset de 0, la consola imprime algo como: Request /transactions completed in 0.0123 seconds. Si después llamas a /plans, verás otro tiempo, normalmente menor, porque cada endpoint tiene su propio costo de procesamiento.
¿Qué errores comunes aparecen al implementar middlewares?
Un detalle que aparece en la clase es un conflicto de nombres. Si en clases anteriores definiste una función llamada time, vas a chocar con la clase time de Python que necesitas importar para medir el tiempo.
La solución es renombrar tu función. En el ejemplo, time pasó a llamarse get_time_by_iso_code, lo que liberó el espacio de nombres y permitió que time.time() funcionara correctamente.
Esta lección aplica a cualquier proyecto Python: evita usar nombres que colisionen con módulos estándar como time, os, json o request.
¿Qué información puedes capturar desde el objeto request?
El parámetro request te da acceso a múltiples atributos útiles. Algunos de los más frecuentes son:
request.urlpara conocer la ruta llamada.request.methodpara saber si fue GET, POST, PUT u otro.request.headerspara inspeccionar los headers enviados por el cliente.request.clientpara identificar la dirección del consumidor.
Esta información te sirve para construir middlewares de auditoría, autenticación ligera o trazabilidad sin modificar tus endpoints.
¿Qué reto puedes resolver para practicar middlewares?
El ejercicio propuesto es claro: crea un nuevo middleware que imprima en la consola todos los headers que llegan a cada endpoint. Es una práctica corta pero te obliga a recorrer request.headers, formatear la salida y entender el orden de ejecución del pipeline.
Cuéntame en los comentarios qué otros middlewares personalizados se te ocurren para tus propios proyectos en FastAPI.