1) Nombres de claves
- Consistencia: elegí
camelCase
o snake_case
y mantenelo.
- Claridad > abreviaturas:
precioUnitario
mejor que prcU
.
- Unidades explícitas cuando aplique:
pesoKg
, duracionMs
, montoArs
.
- Plural vs singular: listas en plural (
items
), elemento en singular (item
).
2) Tipos de datos correctos
- Boolean reales (
true/false
), nunca strings "true"
.
- Números: preferí enteros para contadores; para dinero, usá decimal (o centavos como
int
).
- Fechas/horas: ISO‑8601 en UTC, p. ej.
"2025-09-09T16:30:00Z"
; con zona, incluí offset.
- Binarios: codificá en Base64.
- Enum: restringí con listas permitidas (
"estado": "pendiente"|"pagado"|"cancelado"
).
3) null vs campo ausente
- Campo ausente: no aplica / desconocido.
null
: aplica pero sin valor.
- Definilo en el contrato y sé consistente (p. ej., JSON Schema).
4) Estructura y profundidad
- Evitá anidación profunda (> 4‑5 niveles). Divide en sub‑recursos o referencias (
clienteId
).
- Arrays: usalos para colecciones homogéneas; si mezclás tipos, justificá y documentá.
- Orden de claves: no es significativo; mantener orden lógico ayuda a diffs/revisiones.
5) Tamaño, paginación y filtros (APIs)
- Paginación:
page
, limit
y metadatos (total
, pages
).
{ "data": [...], "pagination": { "page": 1, "limit": 20, "total": 347 } }
- Filtros y orden por query params (
?search=teclado&sort=precio:desc
).
- Límites de tamaño; compresión GZIP/Brotli.
6) Envoltorios de respuesta
Elegí un estilo y mantenelo:
- Plano: devolver directamente el recurso o lista.
- Envoltorio:
data
+ meta/pagination/errors
. Coherencia = clientes más simples.
7) Errores estructurados
Recomendado Problem Details (RFC 7807):
{
"type": "https://api.ejemplo.com/errors/validation",
"title": "Error de validación",
"status": 400,
"detail": "precio debe ser > 0",
"errors": { "precio": ["Debe ser mayor a 0"] }
}
8) Versionado y compatibilidad
- Versioná la API:
/v1/
o content‑negotiation (Accept: application/vnd.miapi.v2+json
).
- Compatibilidad hacia atrás: agregar campos debería ser tolerado.
- Remociones/cambios: período de deprecación + comunicación.
9) Validación con JSON Schema
- Definí
types
, required
, rangos, pattern
, enum
.
- Validá requests y opcionalmente responses; versioná esquemas y usá contract tests.
10) Serialización estable
- Pretty‑print solo para logs/dev; producción compacto.
- Para diffs determinísticos, usá serialización canónica (claves ordenadas).
- Formato de fechas único y zona (ideal UTC).
11) Seguridad
- Content‑Type correcto:
application/json; charset=utf-8
.
- Tamaño máximo de payload; rechazá cuerpos gigantes.
- Sanitización: validá todo input; no confíes en el cliente.
- Redacción de PII/secretos en logs.
- CORS configurado.
- Rate limiting / idempotency‑key en POST sensibles.
- Evitá JSON hijacking y CSRF: encabezados adecuados y autenticación fuerte.
12) Internacionalización y texto
- Siempre UTF‑8.
- Evitá escapar Unicode innecesariamente (p. ej., opciones como
JSON_UNESCAPED_UNICODE
).
13) Comentarios y documentación
- JSON no admite comentarios. Si necesitás anotaciones, agregá campos explícitos (p. ej.
_meta
) o documentá en OpenAPI/Swagger.
- Proveé ejemplos válidos y casos de error en la documentación.
14) Actualizaciones parciales
- Merge Patch (
application/merge-patch+json
) para cambios simples:
{ "precio": 1399.99 }
- JSON Patch (
application/json-patch+json
) para operaciones declarativas:
[{ "op": "replace", "path": "/precio", "value": 1399.99 }]
15) Rendimiento
- Compresión en tránsito (GZIP/Brotli).
- Solo campos necesarios (proyecciones).
- NDJSON para streaming de muchos registros.
- En BDs relacionales: columnas virtuales + índices sobre propiedades JSON.
16) Ejemplo de contrato sano
{
"id": 101,
"descripcion": "Teclado mecánico",
"precioArs": 1200.50,
"disponible": true,
"tags": ["periferico", "oferta"],
"creadoEn": "2025-09-09T16:30:00Z",
"meta": {
"moneda": "ARS",
"fuente": "catalogo"
}
}
Notas: nombres consistentes, unidades explícitas, fecha ISO‑8601 en UTC; meta
para datos operativos que el cliente puede ignorar.
17) Checklist rápido
- Naming consistente (camelCase/snake_case), sin abreviaturas crípticas.
- Fechas ISO‑8601 en UTC.
- Dinero como decimal/entero (centavos), no float.
null
vs ausente definidas.
- Validación con JSON Schema.
- Errores estructurados (RFC 7807).
- Paginación y filtros en listados.
- Tamaño y compresión controlados.
- Seguridad: headers, rate limit, redacción de logs.
- Versionado y compatibilidad hacia atrás.
18) Antipatrones comunes (y cómo corregirlos)
- Booleans como string:
"activo": "true"
→ true
.
- Fechas sueltas:
"09/09/25"
→ "2025-09-09T00:00:00Z"
.
- Dinero en float: errores de coma flotante; usar decimal o centavos enteros.
- Campos sobrecargados: dividir en
estado
+ subestado
o motivo
.
- Respuestas inconsistentes entre endpoints: unificar envoltorio, nombres y formatos.
- Anidación excesiva: normalizar o referenciar por id.
19) Herramientas útiles
- Validadores: JSON Schema (AJV en JS, jsonschema en Python).
- Formatters/linters: Prettier, VS Code, jq.
- Documentación: OpenAPI/Swagger con ejemplos request/response.
- Pruebas: contract testing (p. ej. Pact), tests de esquema en CI.
Aplicando estas prácticas obtenés JSON predecible, seguro, eficiente y fácil de mantener, reduciendo errores de integración y facilitando la evolución de tus APIs y servicios.