Diseño de API REST: Hazlo Obvio
Una buena API es una que el desarrollador puede adivinar. Si necesitan /users, GET /users debería funcionar. Si necesitan el usuario 42, GET /users/42 debería funcionar. Cuando las APIs siguen patrones consistentes, la documentación se vuelve opcional para operaciones comunes.
Nomenclatura de Recursos
| Haz | No Hagas | Por Qué |
|---|---|---|
GET /users | GET /getUsers | El método HTTP es el verbo |
GET /users/42 | GET /user/42 | Las colecciones son plurales |
POST /users | POST /createUser | POST ya significa "crear" |
GET /users/42/orders | GET /getUserOrders?userId=42 | Recursos anidados muestran relaciones |
kebab-case en URLs | camelCase o snake_case | URLs son case-insensitive por convención |
Métodos HTTP
GET /users → Listar usuarios
GET /users/42 → Obtener usuario 42
POST /users → Crear un usuario (body tiene datos)
PUT /users/42 → Reemplazar usuario 42 completamente
PATCH /users/42 → Actualizar campos específicos del usuario 42
DELETE /users/42 → Eliminar usuario 42Paginación
Basada en offset (simple, más común):
GET /users?page=2&limit=20
{
"data": [...],
"meta": {
"page": 2,
"limit": 20,
"total": 156,
"total_pages": 8
}
}Basada en cursor (mejor para datasets grandes, datos en tiempo real):
GET /users?cursor=eyJpZCI6NDJ9&limit=20
{
"data": [...],
"meta": {
"next_cursor": "eyJpZCI6NjJ9",
"has_more": true
}
}Respuestas de Error
Sé consistente. Elige un formato y mantenlo:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "La validación de la solicitud falló",
"details": [
{ "field": "email", "message": "Debe ser un email válido" },
{ "field": "age", "message": "Debe ser al menos 18" }
]
}
}Siempre incluye: código de error legible por máquina, mensaje legible por humano y detalles por campo para errores de validación.
Versionamiento
| Estrategia | Ejemplo | Pros/Contras |
|---|---|---|
| Path en URL | /api/v1/users | Simple, explícito, fácil de enrutar. Más común. |
| Header | Accept: application/vnd.api+json;version=1 | URLs limpias, más difícil probar en browser. |
| Query param | /users?version=1 | Fácil de agregar, contamina query string. |
Versionamiento por path en URL gana en simplicidad. Versiona solo cuando tengas breaking changes.
Filtrado, Ordenamiento y Campos
// Filtrado
GET /users?role=admin&status=active
// Ordenamiento
GET /users?sort=-created_at,name // prefijo - = descendente
// Campos esparsos (retorna solo lo necesario)
GET /users?fields=id,name,email
// Búsqueda
GET /users?q=johnAutenticación
// Bearer token (más común para APIs)
GET /users HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
// API key (para server-to-server)
GET /users HTTP/1.1
X-API-Key: sk_live_abc123Herramienta de referencia: Códigos de Estado HTTP — elige el status code correcto para cada respuesta.