Backend Python y FastAPI — API modernas y escalables
FastAPI es el framework de referencia en Python para API REST asíncronas. Combina las anotaciones de tipos nativas de Python con validación automática mediante Pydantic, documentación OpenAPI generada sola y un rendimiento ASGI comparable al de Node.js, sin sacrificar la legibilidad del código.
FastAPI: el framework Python más rápido
FastAPI se ejecuta sobre Uvicorn (servidor ASGI) con Gunicorn para el modo multiproceso en producción. Un endpoint sencillo que lee de la caché de Redis responde en menos de 5 ms en hardware estándar. La inyección de dependencias nativa permite probar cada capa de forma aislada sin mocks complicados: la autenticación, la sesión de base de datos o la limitación de peticiones son, cada una, una dependencia inyectable.
La documentación OpenAPI 3.1 se genera automáticamente a partir de las anotaciones de tipos: en desarrollo, Swagger UI y ReDoc quedan disponibles en `/docs` y `/redoc`. El esquema de Pydantic v2 (validador escrito en Rust) valida peticiones y respuestas entre 10 y 20 veces más rápido que Pydantic v1. Cualquier campo inválido devuelve un 422 con mensajes de error claros y localizados.
- async/await nativo: entrada y salida no bloqueante en todas las operaciones de base de datos y HTTP
- BackgroundTasks para el trabajo posterior a la respuesta (correo, webhook, registro)
- Compatibilidad nativa con WebSocket para funciones en tiempo real (chat, notificaciones)
- Limitación de peticiones con slowapi (basada en limits): por IP y por usuario
- Middleware de CORS, compresión (gzip/brotli), identificador de petición y medición de tiempos
PostgreSQL, SQLAlchemy y Alembic
Usamos SQLAlchemy 2.0 async (controlador asyncpg) para todas las operaciones de base de datos. Los modelos se definen con Mapped types: con tipado seguro y sin cadenas de texto. Las consultas complejas se escriben en SQLAlchemy Core (verificado en tiempo de compilación) o en SQL puro mediante `text()` con parámetros enlazados; nunca por interpolación de cadenas, lo que elimina por completo el riesgo de inyección SQL.
Las migraciones de Alembic se autogeneran a partir de los cambios en los modelos y se revisan a mano antes de aplicarlas. Cada migración tiene su `upgrade()` y su `downgrade()` probados. En producción, las migraciones se ejecutan en CI antes del despliegue, de modo que la base de datos siempre está sincronizada con el código. El pool de conexiones lo gestiona asyncpg, con un tamaño configurable por servicio.
- Bloqueo a nivel de fila con `SELECT ... FOR UPDATE` para operaciones concurrentes críticas
- Búsqueda de texto completo con pg_trgm y tsvector: sin Elasticsearch en los casos sencillos
- JSONB para datos semiestructurados, con índices GIN
- Tablas particionadas para tablas de millones de filas (registros, eventos)
Caché en Redis y escalado horizontal
Redis 7 se usa como caché de aplicación (TTL por endpoint), almacén de sesiones (tokens de refresco JWT con revocación selectiva), pub/sub para eventos en tiempo real y cola para trabajos en segundo plano (Celery o ARQ). La estrategia de caché es cache-aside con invalidación explícita, no un TTL a ciegas que pueda servir datos obsoletos.
- Autenticación JWT con token de acceso (15 min) y token de refresco en Redis (7 días)
- Celery con Redis como broker para tareas asíncronas (generación de PDF, correo, importaciones)
- Endpoint de health check `/health` con el estado de la base de datos, Redis y la versión desplegada
- Registro estructurado en JSON (structlog), compatible con Loki, Datadog y ELK
Ventajas y limitaciones
Ventajas
- Rendimiento ASGI comparable al de Node.js y Go en operaciones de entrada y salida.
- Documentación OpenAPI generada automáticamente a partir de las anotaciones de tipos.
- Validación rápida con Pydantic v2 y errores 422 claros.
- Código legible: Python resulta familiar para la mayoría de los equipos.
Limitaciones
- Python sigue siendo más lento que Go o Rust en tareas intensivas de CPU.
- async/await exige disciplina: una llamada bloqueante detiene todo el bucle de eventos.
- Ecosistema más joven que el de Django en cuanto a funciones incluidas de serie.
- No trae ORM ni panel de administración integrados: se eligen por separado.
Veredicto breve
Elige FastAPI para API REST asíncronas, microservicios y backends de aplicaciones SPA o móviles. Para cargas extremas de CPU o para monolitos con panel de administración ya hecho, Go y Django, respectivamente, pueden encajar mejor.
Tabla de especificaciones
| Capacidad | Límite / umbral | Uso habitual | |
|---|---|---|---|
| Concurrencia | async/await, entrada y salida no bloqueante | El trabajo intensivo de CPU requiere procesos aparte | API con muchas llamadas a base de datos o HTTP |
| Latencia | Menos de 5 ms por endpoint con caché en Redis | Aumenta al serializar cargas útiles grandes | Backends de SaaS, móvil y tiempo real |
| Validación y documentación | Pydantic v2 y OpenAPI 3.1 automático | Los esquemas complejos alargan el arranque | API públicas con Swagger o ReDoc |
| Coste típico | Open source, funciona con 1 vCPU | El escalado horizontal exige varios procesos | Del MVP a producción |
FastAPI frente a las alternativas
| Criterio | FastAPI | Django / Express |
|---|---|---|
| Rendimiento asíncrono | Excelente (ASGI nativo) | Django parcial, Express bueno |
| Documentación OpenAPI automática | Sí, a partir de las anotaciones de tipos | Requiere paquetes adicionales |
| Admin y ORM incluidos | No (se eligen por separado) | Django: sí; Express: no |
Preguntas frecuentes
¿FastAPI es más rápido que Django?
En entrada y salida, sí. FastAPI se ejecuta de forma asíncrona sobre ASGI, así que atiende muchas más peticiones concurrentes con llamadas a base de datos o HTTP que el Django síncrono clásico. Django, en cambio, incluye más funciones de serie.
¿Para qué no es adecuado FastAPI?
Para tareas intensivas de CPU (procesado de imágenes, cálculo numérico pesado) Python es más lento que Go o Rust, así que ese trabajo se traslada a procesos aparte. Además, no incluye un panel de administración listo para usar como el de Django.
¿FastAPI necesita un ORM?
No necesariamente. Nosotros usamos SQLAlchemy 2.0 async con Alembic para las migraciones, pero también puedes escribir SQL puro. El ORM no viene incluido, así que lo eliges según el proyecto.
¿Cómo escalo un backend FastAPI?
En horizontal: se ejecutan varios procesos Uvicorn bajo Gunicorn, detrás de un balanceador de carga, con caché en Redis y las tareas pesadas trasladadas a Celery. El diseño sin estado permite añadir instancias cuando hace falta.