¿Por qué tus APIs fallan? La verdad sobre REST
REST no es solo PUT y GET. Entendé los principios que hacen que una API funcione de verdad y no sea un dolor de cabeza para mantener.
NUCBA
¿Por qué tus APIs fallan? La verdad sobre REST
Hay una diferencia enorme entre hacer una API y hacer una API REST. La primera la podés armar en una tarde, la segunda te va a ahorrar meses de dolores de cabeza.
REST no es una tecnología ni un framework. Es un conjunto de principios arquitectónicos que, cuando los aplicás bien, hacen que tu API sea predecible, escalable y fácil de mantener. Cuando los ignorás, terminás con un frankenstein de endpoints que nadie entiende.
Qué significa REST realmente
REST viene de "Representational State Transfer". Suena académico, pero en la práctica significa que tu API trata a los recursos como objetos que podés manipular de forma consistente.
Pensalo así: en lugar de tener endpoints como /getUserData o /createNewPost, tenés recursos como /users/123 o /posts/456. La diferencia no es cosmética, cambia completamente cómo pensás y organizás tu código.
Los principios que importan
Client-Server: Tu API y tu frontend son cosas separadas. La API no sabe ni le importa si la está consumiendo React, una app móvil o Postman.
Stateless: Cada request tiene toda la información que necesita. No guardás estado del cliente en el servidor. Esto significa que podés escalar horizontalmente sin problemas.
Uniform Interface: Usás los métodos HTTP para lo que fueron diseñados y estructurás tus URLs de forma consistente.
Los métodos HTTP como herramientas
Acá es donde muchos se equivocan. Los métodos HTTP no son sugerencias, son herramientas específicas para acciones específicas.
GET - Para obtener datos
// Obtener todos los usuarios GET /users // Obtener un usuario específico GET /users/123 // Obtener los posts de un usuario GET /users/123/posts
GET tiene que ser "safe" e "idempotent". Traducido: no modifica nada y podés llamarlo mil veces que el resultado es el mismo.
POST - Para crear recursos
// Crear un usuario nuevo POST /users Content-Type: application/json { "name": "Juan Pérez", "email": "juan@ejemplo.com" }
POST no es idempotent. Si lo llamás dos veces, creás dos usuarios.
PUT - Para actualizar o crear
// Actualizar usuario completo PUT /users/123 Content-Type: application/json { "id": 123, "name": "Juan Carlos Pérez", "email": "juancarlos@ejemplo.com" }
PUT es idempotent. Podés llamarlo las veces que quieras, el resultado es el mismo.
PATCH - Para actualizaciones parciales
// Actualizar solo el email PATCH /users/123 Content-Type: application/json { "email": "nuevo@ejemplo.com" }
DELETE - Para eliminar
// Eliminar usuario DELETE /users/123
Cómo estructurar URLs que no den vergüenza
Tus URLs tienen que contar una historia clara. Acá van las reglas que funcionan:
Usa sustantivos, no verbos
Mal:
/getUsers/createUser/updateUserEmail
Bien:
/users/users/123/users/123/posts
Jerárquico y lógico
// Usuario específico /users/123 // Posts de ese usuario /users/123/posts // Post específico de ese usuario /users/123/posts/456 // Comentarios de ese post /users/123/posts/456/comments
Plurales para colecciones
/userspara la colección/users/123para un elemento específico
Status codes que comunican
Los códigos de estado no son decoración, son información crucial para quien consume tu API.
Los que tenés que conocer
- 200 OK: Todo bien, acá está tu data
- 201 Created: Se creó el recurso (ideal para POST)
- 204 No Content: Todo bien, pero no hay contenido que devolver (ideal para DELETE)
- 400 Bad Request: El cliente mandó algo mal
- 401 Unauthorized: Falta autenticación
- 403 Forbidden: Tenés autenticación pero no permisos
- 404 Not Found: El recurso no existe
- 409 Conflict: Hay un conflicto (ej: email duplicado)
- 500 Internal Server Error: Se rompió algo del lado del servidor
Ejemplo práctico: API de blog
Vamos con un ejemplo completo de cómo quedaría una API REST para un blog:
// Obtener todos los posts GET /posts Response: 200 OK [ { "id": 1, "title": "Mi primer post", "author_id": 123 }, { "id": 2, "title": "Segundo post", "author_id": 124 } ] // Crear nuevo post POST /posts Content-Type: application/json { "title": "Nuevo post", "content": "Contenido del post...", "author_id": 123 } Response: 201 Created { "id": 3, "title": "Nuevo post", "content": "Contenido del post...", "author_id": 123, "created_at": "2024-01-15T10:30:00Z" } // Actualizar post PUT /posts/3 Content-Type: application/json { "title": "Post actualizado", "content": "Contenido actualizado...", "author_id": 123 } Response: 200 OK // Eliminar post DELETE /posts/3 Response: 204 No Content
Errores comunes que arruinan todo
Mezclar acciones con recursos
// Mal POST /users/login POST /users/logout POST /posts/publish // Mejor POST /sessions (para login) DELETE /sessions/current (para logout) PATCH /posts/123 { "status": "published" }
URLs inconsistentes
// Mal - mezcla criterios /user/123 /posts /comment/456 // Bien - consistente /users/123 /posts /comments/456
Ignorar los status codes
// Mal - siempre 200 Response: 200 OK { "success": false, "error": "Usuario no encontrado" } // Bien - usar el código correcto Response: 404 Not Found { "error": "Usuario no encontrado", "code": "USER_NOT_FOUND" }
Por qué REST funciona en equipos
Cuando seguís los principios REST, cualquier dev que se sume a tu proyecto entiende la API sin explicaciones. No necesita documentación extensa ni sesiones de onboarding para entender qué hace cada endpoint.
Además, las herramientas se adaptan mejor. Los browsers cachean requests GET automáticamente. Los proxies pueden routear basándose en métodos HTTP. Los logs son más fáciles de analizar.
Preguntas frecuentes
¿Siempre tengo que seguir REST al pie de la letra?
No. REST es una guía, no una religión. Si necesitás un endpoint /search que no mapea perfectamente a un recurso, hacelo. Pero que sea la excepción, no la regla.
¿Qué hago con acciones complejas como "enviar email" o "procesar pago"?
Podés tratarlas como recursos. En lugar de /sendEmail, creá un recurso /emails con POST. En lugar de /processPayment, creá /payments. Pensá en el resultado de la acción como un recurso.
¿REST funciona para APIs internas también?
Absolutamente. Especialmente para APIs internas, donde la consistencia te ahorra tiempo de desarrollo y debugging. Tu equipo te va a agradecer tener APIs predecibles.