💡 Key Takeaways
- Resource Naming: The Foundation That Everyone Gets Wrong
- HTTP Methods and Status Codes: Speak the Language Correctly
- Versioning: Future-Proofing Without the Pain
- Pagination, Filtering, and Sorting: Handling Large Datasets
Hace tres años, vi cómo una startup consumía $2.3 millones en financiación porque su diseño de API estaba tan fundamentalmente roto que cada nueva característica requería reescribir la mitad de su código base. Soy Sarah Chen, y he pasado los últimos 12 años como arquitecta principal de API en tres diferentes startups unicornio, diseñando sistemas que manejan más de 47 mil millones de solicitudes por mes. Lo que he aprendido es que el diseño de API REST no se trata de seguir reglas rígidas, sino de tomar decisiones deliberadas que se convierten en excelencia técnica o deuda técnica.
💡 Puntos Clave
- Nombres de Recursos: La Base Que Todos Se Equivocan
- Métodos HTTP y Códigos de Estado: Hablar el Lenguaje Correctamente
- Versionado: A Prueba de Futuro Sin el Dolor
- Paginación, Filtrado y Ordenamiento: Manejo de Grandes Conjuntos de Datos
El panorama ha cambiado drásticamente desde que REST se convirtió en el estándar de facto. En 2026, estamos lidiando con computación en el borde, aplicaciones impulsadas por IA que realizan miles de llamadas API por segundo, y usuarios que esperan tiempos de respuesta de menos de 100 ms desde cualquier parte del planeta. El antiguo consejo de "solo sigue los principios REST" ya no es suficiente. Necesitas una lista de verificación práctica y probada en batalla que tenga en cuenta las realidades modernas.
Este artículo es esa lista de verificación. Estoy compartiendo el marco exacto que utilizo al arquitectar APIs para empresas que procesan millones de ingresos por día. Estas no son mejores prácticas teóricas; son los patrones que separan las APIs que escalan de las APIs que colapsan bajo su propio peso.
Nombres de Recursos: La Base Que Todos Se Equivocan
Permíteme comenzar con algo que parece trivial pero causa más problemas a posteriori que casi cualquier otra cosa: nombrar recursos. He revisado más de 200 diseños de API en mi carrera, y estimo que el 60% de ellos tenían nombres de recursos inconsistentes o confusos que creaban problemas en cascada.
Aquí está el principio central: tus URLs deberían leerse como frases que describen la jerarquía de recursos. Usa sustantivos plurales para colecciones, mantén la anidación superficial (máximo 2-3 niveles) y sé implacablemente consistente. Cuando me uní a mi empresa actual, su API tenía puntos finales como /getUser, /user-list, y /users/fetch, todos haciendo cosas similares. Pasamos tres meses desentrañando el lío.
El patrón que recomiendo:
- Colecciones:
/api/v1/users,/api/v1/orders,/api/v1/products - Recursos específicos:
/api/v1/users/12345,/api/v1/orders/ord_abc123 - Sub-recursos:
/api/v1/users/12345/orders,/api/v1/orders/ord_abc123/items - Acciones sobre recursos:
/api/v1/orders/ord_abc123/cancel(POST),/api/v1/users/12345/verify-email(POST)
¿Notas lo que falta? Verbos en la ruta de la URL (excepto para acciones que no son CRUD). El método HTTP ES el verbo. GET /users significa "obtener usuarios." POST /users significa "crear un usuario." DELETE /users/123 significa "eliminar al usuario 123." Esto no es solo estético; hace que tu API sea predecible y reduce la carga cognitiva sobre los desarrolladores.
Para operaciones no CRUD, utilizo un enfoque pragmático. Sí, los puristas dirán que todo debería mapearse a CRUD, pero en el mundo real, tienes operaciones como "cancelar un pedido," "verificar un correo electrónico," o "calcular el envío." Yo represento estas como solicitudes POST a puntos finales de acción: POST /orders/123/cancel. La clave es la consistencia: documenta tu patrón y cúmplelo religiosamente.
Un detalle crítico más: usa kebab-case para recursos de múltiples palabras (/shipping-addresses, no /shippingAddresses o /shipping_addresses). Las URLs son insensibles a mayúsculas en muchos contextos, y el kebab-case es el formato más universalmente legible. He visto incidentes en producción causados por problemas de sensibilidad a mayúsculas que se podrían haber evitado con esta simple convención.
Métodos HTTP y Códigos de Estado: Hablar el Lenguaje Correctamente
Si nombrar recursos es el vocabulario de tu API, los métodos HTTP y los códigos de estado son su gramática. Y al igual que en el lenguaje humano, usar la gramática incorrecta te hace difícil de entender, incluso si la gente eventualmente puede averiguar lo que quieres decir.
Veo dos patrones anti-comunes repetidamente. Primero, APIs que usan POST para todo porque "funciona". Segundo, APIs que devuelven 200 OK para cada respuesta, incluso errores, con el estado real enterrado en el cuerpo de la respuesta. Ambos patrones crean APIs que son más difíciles de almacenar en caché, más difíciles de depurar y más difíciles de integrar con herramientas estándar.
Aquí está mi desglosado método por método basado en el uso del mundo real:
GET: Recuperar recursos. Debe ser idempotente y seguro (sin efectos secundarios). Nunca uses GET para operaciones que modifiquen el estado; no me importa si es "solo actualizar una marca de tiempo de último acceso." Para eso están los middleware. Las solicitudes GET deben ser almacenables en caché, y mezclar cambios de estado rompe las suposiciones de caché. En un sistema en el que trabajé, vimos una reducción del 73% en la carga de la base de datos solo al implementar correctamente la idempotencia de GET y agregar encabezados de caché HTTP.
POST: Crear nuevos recursos o activar acciones. POST es tu caballo de trabajo para operaciones no idempotentes. Al crear recursos, devuelve 201 Created con un encabezado Location apuntando al nuevo recurso. Al activar acciones, devuelve 200 OK o 202 Accepted (para operaciones asíncronas) con un cuerpo de respuesta que describe el resultado.
PUT: Reemplazar un recurso completo. Aquí es donde muchos desarrolladores se confunden. PUT debería reemplazar el recurso completo con la representación proporcionada. Si envías una solicitud PUT con solo algunos campos, esos son los únicos campos que el recurso debería tener después (otros campos deberían establecerse en valores predeterminados o nulos). En la práctica, uso PUT con moderación; generalmente solo para recursos donde los clientes realmente gestionan el estado completo.
PATCH: Actualizar parcialmente un recurso. Esto es lo que la mayoría de los desarrolladores realmente quieren cuando piensan que quieren PUT. PATCH te permite enviar solo los campos que deseas cambiar. Uso típicamente JSON Patch (RFC 6902) o JSON Merge Patch (RFC 7396) para el formato de solicitud. En mi empresa actual, el 94% de nuestras operaciones de actualización utilizan PATCH, no PUT.
DELETE: Eliminar un recurso. Devuelve 204 No Content en caso de éxito (no se necesita cuerpo de respuesta), o 200 OK si estás devolviendo información sobre la eliminación. Asegúrate de que DELETE sea idempotente; llamarlo varias veces debería tener el mismo efecto que llamarlo una vez. Devuelve 204 incluso si el recurso ya fue eliminado.
Para los códigos de estado, utilizo este subconjunto práctico que cubre el 99% de los escenarios:
- 200 OK: GET, PUT, PATCH, o POST exitoso que devuelve datos
- 201 Created: POST exitoso que crea un recurso
- 202 Accepted: Solicitud aceptada para procesamiento asíncrono
- 204 No Content: DELETE exitoso o actualización sin cuerpo de respuesta
- 400 Bad Request: El cliente envió datos inválidos (con mensaje de error detallado)
- 401 Unauthorized: Se requiere autenticación o fallida
- 403 Forbidden: Autenticado pero no autorizado para este recurso
- 404 Not Found: El recurso no existe
- 409 Conflict: Solicitud en conflicto con el estado actual (por ejemplo, correo electrónico duplicado)
- 422 Unprocessable Entity: La validación falló (prefiero esto sobre 400 para errores de validación)
- 429 Too Many Requests: Límite de tasa excedido
- 500 Internal Server Error: Algo falló de nuestra parte
- 503 Service Unavailable: Interrupción temporal o mantenimiento
La clave es: los códigos de estado son para semánticas a nivel de HTTP, los cuerpos de respuesta son para detalles a nivel de aplicación. Una respuesta 400 siempre debería significar "enviaste datos incorrectos", pero el cuerpo de respuesta explica exactamente qué estaba mal con qué campo.
Versionado: A Prueba de Futuro Sin el Dolor
He vivido a través de tres migraciones importantes de versiones de API, y cada una me enseñó algo doloroso sobre qué no hacer. La peor fue una migración de v1 a v2 que tomó 18 meses y requirió coordinar actualizaciones en 47 aplicaciones de cliente. Perdimos dos clientes importantes durante ese proceso porque sus equipos de integración no pudieron mantenerse al día con los cambios.
| Enfoque | Patrón de URL | Escalabilidad | Mantenibilidad |
|---|---|---|---|
| RESTful (Recomendado) | /users/{id}/orders | Excelente - Jerarquía clara, cacheable | Alto - Patrones predecibles |
| RPC-Style (Anti-patrón) | /getUser, /fetchOrders | Pobre - Sin caché, basado en verbos | Bajo - Nombres inconsistentes |