Uso de JSON en APIs REST: mejores prácticas
JSON en las APIs REST
JSON y las APIs REST son una combinación perfecta. La sintaxis ligera de JSON, su soporte nativo de arrays y su soporte universal en los lenguajes lo convierten en el formato predeterminado para las APIs web modernas. Pero simplemente usar JSON en tu API no es suficiente -- seguir convenciones establecidas y mejores prácticas garantiza que tu API sea consistente, intuitiva y fácil de integrar.
Formato de solicitud y respuesta
Estructura de sobre (envelope) consistente
Adopta un sobre JSON consistente para todas las respuestas de la API. Esto hace que el procesamiento en el lado del cliente sea predecible y simplifica el manejo de errores.
{
"status": "success",
"data": {
"user": {
"id": 123,
"name": "Alice",
"email": "alice@example.com"
}
},
"meta": {
"requestId": "req-a1b2c3d4",
"timestamp": "2026-07-19T10:30:00Z"
}
}
Snake Case vs Camel Case
Elige una convención de nomenclatura y mantente fiel a ella en toda tu API:
- Camel Case (
createdAt,firstName): Común en los ecosistemas JavaScript/TypeScript - Snake Case (
created_at,first_name): Común en los ecosistemas de Python, Ruby y PHP
Sea cual sea la que elijas, documéntala claramente y considera usar una capa de transformación si el lenguaje de tu backend usa una convención diferente.
Códigos de estado HTTP con JSON
Los códigos de estado HTTP adecuados complementan tus respuestas JSON. Úsalos de forma consistente:
| Código de estado | Significado | Cuándo usarlo |
|-------------|---------|-------------|
| 200 OK | Éxito | Éxito de GET, PUT, PATCH |
| 201 Created | Recurso creado | Éxito de POST |
| 204 No Content | Eliminación exitosa | Éxito de DELETE (sin cuerpo JSON) |
| 400 Bad Request | Sintaxis JSON no válida | Cuerpo de solicitud malformado |
| 401 Unauthorized | Autenticación requerida | Token faltante o no válido |
| 403 Forbidden | Permisos insuficientes | Autenticación válida pero no permitido |
| 404 Not Found | El recurso no existe | ID o ruta no válidos |
| 422 Unprocessable Entity | Fallo de validación | Errores semánticos en JSON válido |
| 429 Too Many Requests | Límite de frecuencia alcanzado | El cliente supera los límites |
| 500 Internal Server Error | Fallo en el lado del servidor | Errores inesperados |
Formato estándar de respuesta de error
{
"status": "error",
"error": {
"code": "VALIDATION_ERROR",
"message": "The request body contains invalid fields",
"details": [
{
"field": "email",
"message": "Must be a valid email address",
"code": "INVALID_FORMAT"
},
{
"field": "age",
"message": "Must be a positive integer",
"code": "OUT_OF_RANGE"
}
]
}
}
Recursos anidados
Representación de relaciones
Las APIs REST frecuentemente necesitan representar recursos relacionados. Aquí hay patrones comunes:
Incrustado (carga ansiosa):
{
"order": {
"id": 5001,
"total": 29.99,
"customer": {
"id": 123,
"name": "Alice",
"email": "alice@example.com"
},
"items": [
{
"productId": 42,
"name": "Widget",
"quantity": 2,
"price": 14.99
}
]
}
}
Referenciado (carga perezosa) -- usa IDs y proporciona endpoints separados:
{
"order": {
"id": 5001,
"total": 29.99,
"customerId": 123,
"itemIds": [101, 102]
}
}
Regla general: Incrusta los datos relacionados que siempre se necesitan juntos. Referencia los datos que se recuperan condicionalmente o en un momento diferente.
Patrones de paginación
Al devolver listas de recursos, la paginación es esencial. Usa un formato de paginación consistente:
Paginación basada en desplazamiento (offset)
{
"status": "success",
"data": [
{ "id": 1, "name": "User 1" },
{ "id": 2, "name": "User 2" }
],
"pagination": {
"page": 1,
"perPage": 20,
"totalItems": 156,
"totalPages": 8,
"links": {
"first": "/api/users?page=1&perPage=20",
"prev": null,
"next": "/api/users?page=2&perPage=20",
"last": "/api/users?page=8&perPage=20"
}
}
}
Paginación basada en cursor (recomendada para grandes conjuntos de datos)
{
"status": "success",
"data": [
{ "id": 100, "name": "User 100" },
{ "id": 101, "name": "User 101" }
],
"pagination": {
"nextCursor": "eyJpZCI6MTAxfQ==",
"hasMore": true
}
}
La paginación basada en cursor es más fiable para datos en tiempo real donde los nuevos registros podrían desplazar los límites de las páginas.
JSON en las solicitudes de API
Cuerpos de solicitud POST / PUT
Acepta JSON con el encabezado Content-Type: application/json:
{
"title": "New Blog Post",
"content": "This is the content...",
"tags": ["json", "rest-api"],
"published": false
}
Actualizaciones parciales con PATCH
Usa PATCH para actualizaciones parciales. Acepta solo los campos que deben cambiar:
// PATCH /api/users/123
{
"email": "newemail@example.com"
}
Filtrado, ordenación y búsqueda
Usa parámetros de consulta para la manipulación de datos, manteniendo limpio el cuerpo JSON:
GET /api/users?filter[role]=admin&sort=-createdAt&search=alice
{
"status": "success",
"data": [ /* filtered, sorted results */ ]
}
Límite de frecuencia (rate limiting)
Incluye información del límite de frecuencia en los encabezados de respuesta y, opcionalmente, en el cuerpo JSON:
{
"status": "error",
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests. Please try again later."
},
"meta": {
"rateLimit": {
"limit": 100,
"remaining": 0,
"resetAt": "2026-07-19T11:00:00Z"
}
}
}
Lista de verificación de mejores prácticas de JSON
- [ ] Usa una nomenclatura de claves consistente (camelCase o snake_case en todo)
- [ ] Devuelve códigos de estado HTTP apropiados con cada respuesta
- [ ] Incluye un formato de error consistente con códigos de error legibles por máquina
- [ ] Pagina los endpoints de listas con un objeto de paginación estandarizado
- [ ] Usa JSON Schema para documentar y validar las estructuras de solicitud/respuesta
- [ ] Establece
Content-Type: application/jsonen todos los endpoints JSON - [ ] Comprime las respuestas JSON con gzip o brotli en producción
- [ ] Aplica límites máximos de tamaño de carga útil (por ejemplo, 1MB predeterminado)
- [ ] Usa HTTPS para cifrar los datos JSON en tránsito
- [ ] Estructura los detalles de error para ayudar a los clientes a depurar sin exponer detalles internos
Validación del JSON de tu API
Pasa tus respuestas de API por un validador JSON para detectar errores de formato antes de que lleguen a los clientes. Respuestas JSON consistentes y válidas hacen que tu API sea fiable y amigable para los desarrolladores. Usa nuestra herramienta Formateador y validador de JSON para probar tus cargas útiles durante el desarrollo.