¿Qué es REST?
REST, o Representational State Transfer, es un estilo arquitectónico para diseñar API HTTP. En lugar de inventar comandos, modelas tu dominio como recursos y utilizas los métodos que HTTP ya define para interactuar con ellos. Un POST /posts crea un post, GET /posts/42 lee uno, PATCH /posts/42 lo actualiza y DELETE /posts/42 lo elimina.
El valor reside en la familiaridad. Cada cliente HTTP, proxy, caché y herramienta ya entiende los métodos, los códigos de estado y los headers. Cuando sigues las convenciones, los clientes pueden predecir cómo se comporta tu API sin necesidad de leer un manual personalizado.
Recursos y URIs
Los recursos son los sustantivos de tu API. Utiliza colecciones en plural e identifica los elementos individuales mediante un id.
GET /posts
POST /posts
GET /posts/42
PUT /posts/42
PATCH /posts/42
DELETE /posts/42
- Usa sustantivos, no verbos. El método es el verbo.
- Usa nombres de colecciones en plural de manera consistente.
- Mantén las URLs en minúsculas con guiones, no uses guiones bajos ni camelCase.
- Anida solo cuando la relación sea esencial, como en
/posts/42/comments. - No incluyas el formato en la ruta; utiliza el header
Accept.
El anidamiento profundo se vuelve incómodo rápidamente. /users/1/posts/2/comments/3 es difícil de construir y documentar; prefiere /comments/3 y deja que los clientes filtren.
Métodos y su semántica
Cada método tiene una semántica definida en la que confían tanto los clientes como la infraestructura.
| Método | Propósito | Seguro | Idempotente |
|---|---|---|---|
| GET | Leer un recurso o colección | Sí | Sí |
| POST | Crear un recurso o disparar una acción | No | No |
| PUT | Reemplazar un recurso | No | Sí |
| PATCH | Actualizar parcialmente un recurso | No | No |
| DELETE | Eliminar un recurso | No | Sí |
Seguro significa que no cambia el estado; idempotente significa que repetirlo tiene el mismo efecto que hacerlo una sola vez. Nunca modifiques datos con GET, ya que los clientes, crawlers y cachés pueden emitir solicitudes GET libremente.
Códigos de estado
Devuelve el código que corresponda a lo sucedido. Esta es la parte de la que más dependen los clientes.
- 200 OK — éxito con cuerpo de respuesta.
- 201 Created — se creó un recurso; incluye un encabezado
Location. - 204 No Content — éxito sin cuerpo, común en DELETE.
- 400 Bad Request — solicitud mal formada.
- 401 Unauthorized — autenticación ausente o inválida.
- 403 Forbidden — autenticado pero sin permisos.
- 404 Not Found — el recurso no existe.
- 409 Conflict — conflicto de estado, como un duplicado.
- 422 Unprocessable Entity — sintácticamente válido pero falla la validación.
- 429 Too Many Requests — límite de tasa excedido; incluye
Retry-After. - 500 Internal Server Error — fallo inesperado del servidor.
Devolver 200 con { "success": false } oculta los fallos a los clientes, cachés y sistemas de monitoreo, y obliga a cada cliente a inventar su propio manejo de errores.
Colecciones: filtrado, ordenación y paginación
Las colecciones necesitan un lenguaje de consultas consistente.
GET /posts?status=published&sort=-createdAt&limit=20&cursor=abc123
- Filtrado con
field=value, y claves repetidas para OR. - Ordenación con
sort=fieldosort=-fieldpara orden descendente. - Paginación con
limitycursor(opageyperPage). - Selección de campos con
fields=id,titlecuando los clientes necesiten menos datos. - Búsqueda con un parámetro
qdedicado.
Prioriza la paginación por cursor para conjuntos de datos grandes o cambiantes, y devuelve siempre el siguiente cursor en la respuesta para que los clientes puedan paginar sin tener que adivinar.
{
"data": [{ "id": "42", "title": "Hello" }],
"pagination": { "nextCursor": "abc123", "hasMore": true }
}
Representaciones y respuestas
Las respuestas son representaciones de recursos. Lo habitual es utilizar JSON con una estructura estable.
{
"id": "42",
"title": "Hello",
"createdAt": "2026-09-15T10:00:00Z"
}
- Utiliza camelCase o snake_case de manera consistente, no ambos.
- Utiliza cadenas en formato ISO 8601 para las fechas.
- Utiliza ids estables como cadenas de texto cuando los clientes puedan exceder la precisión numérica.
- Envuelve las colecciones con
dataypagination, pero devuelve los recursos individuales directamente. - Soporta
Accepty configuraContent-Typecorrectamente.
Ausencia de estado (Statelessness) y almacenamiento en caché
Cada solicitud debe contener todo lo necesario para procesarla: la URL, el método, los headers y el cuerpo. No dependas de la memoria del servidor entre solicitudes; esto es lo que permite ejecutar múltiples instancias detrás de un load balancer.
Dado que GET es seguro y las respuestas son autónomas, REST funciona muy bien con el almacenamiento en caché de HTTP. Configura Cache-Control y validadores como ETag en los recursos almacenables en caché, tal como se explica en la guía de HTTP.
Errores
Utiliza un formato de error consistente en todo el proyecto y documéntalo.
{
"error": {
"code": "validation_error",
"message": "Title is required",
"details": [{ "field": "title", "issue": "required" }]
}
}
Un code legible por máquina permite que los clientes tomen decisiones lógicas, un message es seguro de mostrar a los usuarios y details ayuda a que los formularios resalten los campos afectados. Combínalo con el código de estado adecuado.
Mejores prácticas
- Modela los recursos con sustantivos y deja que los métodos expresen las acciones.
- Devuelve el código de estado más específico posible.
- Versiona la API antes de que sea estrictamente necesario y documéntala (consulta API Versioning).
- Pagina cada colección y establece un límite de
limit. - Valida la entrada y devuelve errores estructurados.
- Utiliza una nomenclatura y un estilo de escritura (casing) consistentes en todo el proyecto.
- Almacena en caché las respuestas GET seguras mediante encabezados explícitos.
- Implementa rate limit y autenticación (consulta Rate Limiting).
Errores comunes
- URLs basadas en verbos que duplican los métodos HTTP.
- Devolver un código 200 en caso de errores.
- Colecciones sin límite y sin paginación.
- Inconsistencia en el uso de mayúsculas/minúsculas, formatos de fecha o estructuras de error.
- Anidamiento profundo que se vuelve imposible de mantener.
- Mutar el estado en peticiones GET.
- Romper la compatibilidad con los clientes al cambiar la estructura de las respuestas sin previo aviso.
Próximos pasos
REST es la forma predeterminada de exponer un backend. Refuérzalo con la guía de HTTP, documéntalo con OpenAPI, haz que evolucione de forma segura con el API Versioning y protégelo mediante Rate Limiting. Compara este modelo con GraphQL cuando los clientes necesiten mayor flexibilidad.