40 Reglas de Diseño de API (FastAPI/Django/Flask)
Cuarenta reglas para APIs web de Python que sean consistentes, seguras, observables y mantenibles en FastAPI, Django REST Framework y Flask.
Receta
Aplicar durante la revisión del diseño de la API antes de la implementación. Mapear las reglas al esquema OpenAPI y a las pruebas de contrato de CI.
Cuándo usar esto:
- Al diseñar una nueva API REST o RPC
- Al revisar solicitudes de extracción (pull requests) que agregan endpoints
- Al estandarizar APIs entre microservicios
Referencia de Reglas de API
| # | Área | Reglas |
|---|---|---|
| 1-10 | URLs y versionado | Diseño de recursos |
| 11-20 | Solicitud/Respuesta | Modelos y validación |
| 21-30 | Errores y seguridad | Experiencia del cliente |
| 31-40 | Operaciones y documentación | Preparación para producción |
Análisis Detallado
URLs y Versionado (1-10)
- Sustantivos plurales para recursos -
/facturas, no/facturani/obtenerFacturas. - Versión en la ruta de la URL -
/api/v1/facturaspara cambios disruptivos. - Recursos anidados máximo 2 niveles -
/clientes/{id}/facturas, no anidamiento más profundo. - Usar métodos HTTP correctamente - GET para leer, POST para crear, PUT/PATCH para actualizar, DELETE para eliminar.
- POST para acciones -
/facturas/{id}/enviarpara operaciones no CRUD. - Paginación en todas las listas -
?limite=50&cursor=abco offset con un límite máximo. - Filtrado a través de parámetros de consulta -
?estado=pagado&desde=2026-01-01, no nuevos endpoints. - Política de barra inclinada final consistente - elegir una; redirigir la otra (Django: configurar
APPEND_SLASH). - Claves de idempotencia en POST - cabecera
Idempotency-Keypara operaciones de pago y creación. - HATEOAS opcional - enlaces en la respuesta cuando los clientes son diversos; omitir para APIs internas.
Solicitud/Respuesta (11-20)
- Modelos Pydantic para FastAPI - esquemas de solicitud y respuesta con ejemplos.
- Serializadores DRF o Pydantic para Django - validar la entrada antes de la lógica de negocio.
- Fechas y horas en formato ISO 8601 - UTC con sufijo
Z:2026-07-09T14:30:00Z. - Decimal para dinero - nunca
floatpara campos de moneda. - UUIDs para IDs públicos - identificadores opacos; IDs de auto-incremento solo internos.
- Sobre consistente u objetos desnudos - elegir un estilo por API; documentarlo.
- Nombres de campo en
snake_case- JSON coincide con las convenciones de Python a menos que un contrato externo requieracamelCase. - Especificación OpenAPI generada - FastAPI automáticamente; DRF con
drf-spectacular; Flask conflask-smorest. - Modelo de respuesta excluye internos - no devolver modelos ORM directamente.
- ETags para GETs cacheados -
If-None-Matchdevuelve 304 cuando no ha cambiado.
Errores y Seguridad (21-30)
- Detalles de Problema RFC 7807 -
{"type", "title", "status", "detail", "instance"}. - Códigos de error consistentes - campo
codelegible por máquina:INVOICE_NOT_FOUND. - 422 para errores de validación - array de detalles a nivel de campo para correcciones del cliente.
- 401 vs 403 correctamente - 401 no autenticado, 403 autenticado pero no autorizado.
- Limitación de tasa (Rate limiting) - por IP y por token;
429con cabeceraRetry-After. - Lista blanca explícita de CORS - nunca
*en producción con credenciales. - Autenticación vía token Bearer o sesión - documentar el esquema en
securitySchemesde OpenAPI. - Límites de tamaño de entrada - tamaño máximo del cuerpo, carga máxima, longitud máxima de la cadena de consulta.
- No datos sensibles en URLs - tokens y contraseñas solo en cabeceras/cuerpo.
- Registro de auditoría de mutaciones - quién cambió qué, cuándo, en todos los POST/PATCH/DELETE.
Operaciones y Documentación (31-40)
- Endpoints de salud y preparación (health/readiness) -
/health(liveness),/ready(dependencias ok). - Registro de solicitudes estructurado - método, ruta, estado, duración_ms, request_id.
- Propagación de ID de correlación -
X-Request-IDde entrada y salida. - OpenAPI publicado -
/docsen desarrollo; especificación exportada en artefacto de CI. - Pruebas de contrato - schemathesis o Dredd contra OpenAPI en CI.
- Cabeceras de deprecación -
Deprecation: truey fecha RFC 8594Sunset:. - Adiciones compatibles con versiones anteriores - nuevos campos opcionales están bien; eliminar campos es un cambio disruptivo.
- Rutas asíncronas para I/O -
async defde FastAPI con drivers de base de datos asíncronos. - Trabajo en segundo plano fuera de la solicitud - Celery, ARQ o
BackgroundTasksde FastAPI para correos electrónicos y exportaciones. - Pruebas de carga antes del lanzamiento - locust o k6 contra staging con volumen de datos similar a producción.
Trampas Comunes
- Devolver objetos ORM - errores de carga diferida y fugas de datos. Solución: esquemas de respuesta explícitos.
- Float para moneda -
0.1 + 0.2 != 0.3. Solución:Decimalen todo lugar donde el dinero toque JSON. - Formas de error inconsistentes - los clientes no pueden parsear. Solución: un esquema de error aplicado por middleware.
- Sin paginación desde el primer día - cambio disruptivo cuando los datos crecen. Solución: paginar desde el primer lanzamiento.
- Desfase de OpenAPI con el código - la documentación miente. Solución: generar la especificación desde el código; probar el contrato en CI.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| GraphQL | Clientes diversos, grafos complejos | Microservicio CRUD simple |
| gRPC | Malla de servicios interna | Clientes de navegador públicos |
| Solo Webhooks | Integración basada en eventos | Se necesita solicitud/respuesta |
Preguntas Frecuentes
¿FastAPI o Django para una nueva API?
FastAPI para microservicios asíncronos. Django para aplicaciones con mucho contenido de administración con ORM y autenticación integrados.
¿JSON `snake_case` o `camelCase`?
snake_case por defecto para APIs de Python. camelCase solo si el contrato del frontend lo requiere (usar alias).
¿Cómo versiono?
Ruta de URL /v1/ para cambios disruptivos. Cambios aditivos dentro de la misma versión.
¿Acciones POST estilo REST o RPC?
REST para recursos. Acciones POST para operaciones que no se mapean a CRUD.
¿Cómo documento los errores?
Sección responses de OpenAPI por endpoint con ejemplo de Detalles de Problema.
¿FastAPI síncrono o asíncrono?
Asíncrono para I/O bound con drivers asíncronos. sync def está bien con pool de hilos para ORMs bloqueantes.
¿Cómo manejo las cargas de archivos?
Multipart con límites de tamaño. Almacenar en almacenamiento de objetos; devolver URL, no bytes de archivo en JSON.
¿Claves API vs JWT?
JWT para sesiones de usuario. Claves API para comunicación de servicio a servicio. Documentar scopes para ambos.
¿Cómo pruebo las APIs?
pytest + TestClient/httpx. Pruebas de contrato desde OpenAPI. Pruebas de integración en base de datos de prueba.
¿Flask en 2026?
Válido para servicios pequeños y extensiones. FastAPI preferido para nuevas APIs asíncronas.
Relacionado
- 50 Reglas de Python - reglas generales
- 30 Reglas de Seguridad - seguridad de API
- Conceptos Básicos de FastAPI - patrones de FastAPI
- Pruebas de APIs Web - pruebas de API
Versiones de Stack: Esta página fue escrita para Python 3.14.0, FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.