Envelope de respuesta

Toda respuesta del API tiene la misma forma — independientemente de si es un GET, POST, PUT, DELETE o una Business Action. Eso facilita el manejo en el cliente: una sola estructura de error, una sola estructura de éxito.

interface ApiResponse<T> {
  data: T | null;
  meta: Record<string, unknown>;
  errors: ApiError[] | null;
}
 
interface ApiError {
  code: string;
  message: string;
  field?: string | null;
}

Las 3 llaves

data

Contiene el resultado en caso de éxito.

  • GET de un registro: el objeto.
  • GET de una lista: un array.
  • POST de creación: el registro creado.
  • DELETE: { deleted: true, id: <id> }.
  • Acciones: depende de la acción.

En caso de error, data siempre es null.

meta

Información secundaria sobre la respuesta:

  • model — nombre del modelo (siempre presente en CRUD).
  • total, page, per_page, pages — paginación (solo en listados).
  • generated_at, cache_ttl_seconds, cached — metadata de caché (solo en /auth/permissions).

errors

Array de errores en caso de falla, null en caso de éxito. Cada error tiene siempre un code (estable, mayúsculas, con guiones bajos) y un message (humano, en español).

Ejemplo: éxito

{
  "data": { "id": 42, "nombre": "Real Brasileño", "abreviatura": "BRL" },
  "meta": { "model": "Moneda" },
  "errors": null
}

Ejemplo: error de validación

{
  "data": null,
  "meta": { "model": "Moneda" },
  "errors": [
    { "code": "UNIQUE", "message": "Registro duplicado", "field": "abreviatura" }
  ]
}

Ejemplo: dependencias bloqueando un DELETE

{
  "data": null,
  "meta": { "model": "Moneda" },
  "errors": [
    {
      "code": "HAS_DEPENDENTS",
      "message": "No se puede eliminar: tiene 108672 registros dependientes",
      "dependents": { "Venta": 9448, "Compra": 917, "Poliza": 265 }
    }
  ]
}

Status code vs envelope

El API combina ambos. El status HTTP indica la categoría general (200/201 éxito, 4xx error de cliente, 5xx error de servidor) y el envelope te da el detalle estructurado. No hace falta parsear el mensaje — usa errors[].code.

HTTPdataerrors
200objetonull
201objetonull
204(vacío)(vacío)
401nullarray
404nullarray
409nullarray
422nullarray