15 Buenas Practicas para Disenar APIs REST en 2026
Una guía completa para diseñar APIs REST profesionales, consistentes y fáciles de consumir.
Introducción
Una API bien diseñada es un placer de usar: es intuitiva, consistente y predecible. Los desarrolladores que la consumen pueden adivinar cómo funciona un endpoint antes de leer la documentación porque sigue convenciones claras. Por el contrario, una API mal diseñada genera frustración, bugs y soporte constante.
En este artículo recopilamos las 15 mejores prácticas que todo desarrollador backend debería seguir al diseñar APIs REST en 2026. Estas convenciones están probadas por las APIs más exitosas del mundo (Stripe, GitHub, Shopify) y te ayudarán a crear interfaces que otros desarrolladores disfruten usar.
1. Usa sustantivos en plural para los recursos
Los endpoints deben representar colecciones de recursos usando sustantivos en plural. Evita verbos en la URL, ya que el método HTTP ya indica la acción. Esto hace que la API sea predecible y siga las convenciones REST.
Correcto: GET /users, POST /users, GET /users/123, DELETE /users/123
Incorrecto: GET /getUser, POST /createUser, GET /getUserById/123
La excepción son las acciones que no encajan naturalmente en CRUD, como POST /users/123/activate o POST /orders/456/refund. Estos sub-recursos de acción son aceptables cuando la operación no se puede expresar limpiamente con métodos HTTP estándar.
2. Usa los códigos de estado HTTP correctamente
Los códigos de estado HTTP comunican el resultado de la operación de forma estandarizada. Usarlos correctamente permite a los clientes manejar respuestas de forma genérica sin parsear el body.
2xx - Éxito: 200 OK (GET, PUT exitoso), 201 Created (POST exitoso, incluir header Location), 204 No Content (DELETE exitoso, sin body de respuesta).
4xx - Error del cliente: 400 Bad Request (datos inválidos), 401 Unauthorized (no autenticado), 403 Forbidden (autenticado pero sin permisos), 404 Not Found (recurso no existe), 409 Conflict (conflicto de estado, como duplicado), 422 Unprocessable Entity (validación fallida), 429 Too Many Requests (rate limit excedido).
5xx - Error del servidor: 500 Internal Server Error (error inesperado), 502 Bad Gateway, 503 Service Unavailable (mantenimiento o sobrecarga).
3. Implementa paginación en colecciones
Nunca devuelvas una colección completa sin paginar. Incluso si hoy tienes 100 registros, mañana podrías tener 100.000. La paginación protege tanto al servidor (memoria, CPU) como al cliente (ancho de banda, renderizado).
Paginación offset-based: GET /users?page=2&limit=20. Simple de implementar pero ineficiente para datasets grandes (el offset alto es costoso en SQL) y propenso a duplicados si se añaden/eliminan registros durante la paginación.
Paginación cursor-based: GET /users?cursor=eyJpZCI6MTAwfQ&limit=20. Más eficiente y consistente, ideal para feeds y listas grandes. El cursor es un token opaco que apunta a la posición exacta en el dataset.
Incluye siempre metadatos de paginación en la respuesta: total de elementos, si hay más páginas, y enlaces next/prev siguiendo el estándar RFC 8288 con headers Link.
4. Versiona tu API desde el día uno
Las APIs evolucionan y los cambios breaking son inevitables. El versionado te permite evolucionar la API sin romper clientes existentes. La estrategia más común y recomendada es el versionado por URL: /api/v1/users, /api/v2/users.
Alternativas incluyen versionado por header (Accept: application/vnd.myapi.v2+json) o por query parameter (/api/users?version=2). Cada enfoque tiene trade-offs, pero el versionado por URL es el más explícito y fácil de entender.
Establece una política clara de deprecación: comunica con antelación cuándo una versión será eliminada, incluye headers Sunset y Deprecation en las respuestas de versiones deprecadas, y proporciona guías de migración claras.
5. Usa autenticación y autorización robustas
Autenticación: Utiliza tokens JWT (JSON Web Tokens) con firma RS256 para APIs stateless, o sesiones con cookies httpOnly para aplicaciones web. OAuth 2.0 con PKCE es el estándar para autorización de terceros. Nunca implementes tu propio sistema de autenticación; usa librerías probadas y auditadas.
Autorización: Implementa control de acceso basado en roles (RBAC) o atributos (ABAC). Cada endpoint debe verificar explícitamente que el usuario autenticado tiene permisos para la operación solicitada. Devuelve 403 Forbidden (no 404) cuando el usuario no tiene permisos, a menos que revelar la existencia del recurso sea un riesgo de seguridad.
Usa siempre HTTPS. Nunca envíes tokens o credenciales por HTTP plano. Implementa rotación de tokens con refresh tokens de vida corta y revocación activa.
6. Diseña respuestas de error consistentes
Define un formato de error estándar y úsalo en toda la API. El estándar RFC 7807 (Problem Details for HTTP APIs) es una excelente base que incluye campos como type (URI que identifica el tipo de error), title (descripción corta), status (código HTTP), detail (descripción detallada) e instance (URI de la instancia específica del error).
Para errores de validación, incluye un array de errores específicos por campo: {"field": "email", "message": "Formato de email inválido", "code": "INVALID_FORMAT"}. Esto permite al cliente mostrar errores específicos junto a cada campo del formulario.
Incluye siempre un código de error legible por máquina (no solo el status HTTP) que el cliente pueda usar para lógica condicional. Por ejemplo, USER_NOT_FOUND, EMAIL_ALREADY_EXISTS, INSUFFICIENT_PERMISSIONS.
7. Usa query parameters para filtrado, ordenación y búsqueda
Los query parameters son el mecanismo estándar para modificar la consulta de una colección. Usa nombres descriptivos y consistentes: GET /products?category=electronics&min_price=100&max_price=500&sort=-created_at&fields=id,name,price.
El prefijo - para ordenación descendente es una convención ampliamente adoptada. El parámetro fields (sparse fieldsets) permite al cliente solicitar solo los campos que necesita, reduciendo el tamaño de la respuesta y mejorando el rendimiento.
Para búsquedas complejas que no caben en query parameters, considera un endpoint POST de búsqueda: POST /products/search con un body JSON que exprese la consulta compleja. Esto es una desviación pragmática de REST puro, pero es una práctica aceptada en la industria.
8. Usa camelCase para JSON, kebab-case para URLs
Las URLs deben usar kebab-case (minúsculas con guiones) porque es más legible y consistente con las convenciones web: /api/v1/user-profiles, /api/v1/shipping-addresses.
Los campos JSON deben usar camelCase (convención JavaScript/TypeScript): {"firstName": "Carlos", "lastName": "García", "createdAt": "2026-01-15T10:30:00Z"}. Si tu API será consumida principalmente por aplicaciones Python o Ruby, snake_case es una alternativa válida, pero sé consistente.
Las fechas deben seguir siempre el formato ISO 8601: 2026-01-15T10:30:00Z para timestamps UTC, 2026-01-15T11:30:00+01:00 para timestamps con zona horaria. Nunca uses timestamps Unix (segundos desde epoch) como formato principal, aunque puedes ofrecerlos como campo adicional.
9. Implementa rate limiting
El rate limiting protege tu API de abuso, ataques de fuerza bruta y uso excesivo por parte de clientes mal programados. Implementa límites por IP, por usuario autenticado y por API key.
Comunica los límites de rate limiting mediante headers estándar: X-RateLimit-Limit (límite total), X-RateLimit-Remaining (solicitudes restantes), X-RateLimit-Reset (timestamp cuando se resetea el contador). Cuando se excede el límite, devuelve 429 Too Many Requests con header Retry-After.
Considera diferentes tiers de rate limiting: endpoints públicos con límites más restrictivos, endpoints autenticados con límites generosos, y endpoints premium con límites elevados para clientes de pago.
10. Usa HATEOAS selectivamente
HATEOAS (Hypermedia as the Engine of Application State) es el principio REST de incluir enlaces a acciones relacionadas en las respuestas. Aunque el HATEOAS puro es raramente implementado, incluir enlaces relevantes mejora la descubribilidad de la API.
Un enfoque pragmático es incluir un objeto _links o links con las acciones disponibles: {"id": 123, "name": "Pedido #123", "links": {"self": "/api/v1/orders/123", "items": "/api/v1/orders/123/items", "cancel": "/api/v1/orders/123/cancel"}}. Esto permite al cliente descubrir acciones disponibles dinámicamente.
11. Soporta PATCH para actualizaciones parciales
PUT reemplaza el recurso completo, mientras que PATCH actualiza parcialmente. En la práctica, la mayoría de actualizaciones son parciales (cambiar solo el email, solo el nombre), por lo que PATCH es más eficiente y seguro. Implementa ambos métodos si tu API lo necesita, pero PATCH debería ser el método principal para actualizaciones.
Considera soportar JSON Patch (RFC 6902) para operaciones de actualización complejas: [{"op": "replace", "path": "/email", "value": "nuevo@email.com"}, {"op": "remove", "path": "/phone"}]. Esto permite operaciones atómicas y precisas sobre el recurso.
12. Implementa idempotencia en operaciones de escritura
Las operaciones PUT y DELETE son idempotentes por definición: ejecutarlas múltiples veces produce el mismo resultado. Para POST, implementa idempotencia mediante un header Idempotency-Key que el cliente genera (normalmente un UUID). Si el servidor recibe dos requests con la misma clave, devuelve la misma respuesta sin duplicar la operación.
Esto es especialmente importante para operaciones de pago, creación de pedidos y cualquier acción donde la duplicación tenga consecuencias graves. Stripe popularizó este patrón y hoy es una práctica estándar en APIs financieras y de e-commerce.
13. Documenta con OpenAPI/Swagger
Una API sin documentación es una API que nadie quiere usar. OpenAPI 3.1 (antes Swagger) es el estándar para documentar APIs REST. Genera la especificación a partir de tu código usando librerías como swagger-jsdoc, drf-spectacular (Django) o springdoc-openapi (Spring Boot).
Ofrece una interfaz interactiva con Swagger UI o Redoc donde los desarrolladores puedan probar los endpoints directamente desde el navegador. Incluye ejemplos de request y response para cada endpoint, descripciones claras de los parámetros, y códigos de error posibles.
14. Usa compresión y caching
Compresión: Habilita compresión gzip o brotli en todas las respuestas. Brotli ofrece mejor ratio de compresión que gzip y es soportado por todos los navegadores modernos. Para APIs con respuestas JSON grandes, la compresión puede reducir el tamaño de respuesta en un 70-90%.
Caching: Implementa headers de caching HTTP adecuados: Cache-Control, ETag y Last-Modified para recursos que cambian con poca frecuencia. Usa ETags con conditional requests (If-None-Match) para devolver 304 Not Modified cuando el recurso no ha cambiado, ahorrando ancho de banda y tiempo de procesamiento.
15. Implementa CORS correctamente
CORS (Cross-Origin Resource Sharing) es esencial para APIs consumidas desde navegadores web. Configura los headers CORS de forma restrictiva: especifica los orígenes permitidos explícitamente (no uses * en producción), define los métodos HTTP permitidos, y limita los headers que el cliente puede enviar.
Para APIs públicas, considera usar un wildcard con restricciones. Para APIs internas, limita los orígenes a tus dominios conocidos. Maneja las peticiones OPTIONS (preflight) de forma eficiente con un tiempo de cache adecuado mediante Access-Control-Max-Age.
Conclusión
Diseñar una buena API REST es un ejercicio de consistencia y empatía. Piensa en los desarrolladores que consumirán tu API y haz que su trabajo sea lo más fácil posible. Sigue convenciones establecidas, documenta exhaustivamente, y proporciona mensajes de error claros y accionables.
Las APIs más exitosas del mundo (Stripe, GitHub, Twilio) son admiradas no solo por su funcionalidad sino por la calidad de su diseño y documentación. Invertir tiempo en diseñar bien tu API desde el principio te ahorrará innumerables horas de soporte, bugs y refactorizaciones futuras.