JSON Toolkit

Che struttura dovrebbe usare una risposta API

In sintesi: Gli oggetti nudi sono puliti finché non ti servono metadati; gli envelope completi sono sicuri ma verbosi. Per la maggior parte dei progetti usa lo stato HTTP per gli esiti e un envelope stabile per i dati.

Intermedio~4 min di letturaPubblicato il 2026-10-30Aggiornato il 2026-10-30
Tre forme di risposta API e i loro compromessi

In sintesi: esprimi gli esiti con codici di stato 4xx/5xx, porta il payload in { "data": ..., "meta": ... }, e passa a un envelope error in caso di fallimento; questo basta per le API interne, e solo le piattaforme pubbliche con molti integratori hanno bisogno di JSON:API o OpenAPI.

Escludi prima l'opzione peggiore: restituire sempre 200 con l'esito in un campo code.

Tre forme

A. Oggetto nudo

{ "id": 1, "name": "demo", "price": 99 }

Pulito, e la semantica HTTP fa il lavoro (404 è 404). Ma nel momento in cui ti servono paginazione, avvisi o un trace id, non c'è posto dove metterli senza cambiare il contratto.

B. Envelope stabile

{
  "data": { "id": 1, "name": "demo" },
  "meta": { "requestId": "abc", "took": 12 }
}

Payload e metadati vivono separati, quindi i nuovi metadati non rimodellano mai data. Costa un livello di annidamento.

C. Envelope per tutto (da evitare)

{ "code": 0, "message": "success", "data": {...} }

La forma non è il peccato; la pratica lo è. Lo stato 200 per ogni esito significa che CDN, gateway, circuit breaker, politiche di retry e dashboard vedono tutti successo. Ogni alert allora richiede un parsing personalizzato.

La raccomandazione

Stato HTTP per l'esito, envelope per il payload.

{
  "data": { "id": 1, "name": "demo" },
  "meta": { "requestId": "req_8f2a", "took": 12 }
}
{
  "error": {
    "code": "ORDER_NOT_FOUND",
    "message": "Order does not exist or was deleted",
    "details": [{ "field": "id", "issue": "not_found" }]
  },
  "meta": { "requestId": "req_8f2a" }
}

Stato 4xx o 5xx; code stabile e leggibile dalla macchina; message per gli umani; details per gli errori di form a livello di campo.

Regole ferree

  1. Gli endpoint di elenco devono portare metadati di paginazione. Senza total o un cursore non c'è paginatore.
  2. Le liste vuote restituiscono [], mai null. null.map è un'interruzione ricorrente.
  3. Timestamp in ISO 8601 con offset. Vedi che formato per i timestamp.
  4. Una convenzione di denominazione. snake_case o camelCase, convertita una volta al confine.
  5. Denaro come unità minori intere o stringhe. 99.99 non è esatto nel floating point binario.
  6. Non confondere null con l'assenza. Vedi null o omettere il campo.

Quando adottare una specifica

  • Piattaforme pubbliche con molti integratori: JSON:API o OpenAPI più un envelope condiviso
  • API interne di un singolo team: l'envelope sopra basta
  • Contratti forti: Schema prima, strutture generate da esso

Le specifiche risparmiano discussioni e riducono il costo di onboarding. Per un team di cinque persone, JSON:API è di solito lavoro negativo.

FAQ

Come devo scegliere tra un oggetto nudo e un envelope?

Usa un envelope quando ti servono paginazione, avvisi o un requestId, così meta può crescere senza rimodellare data. Restituisci l'oggetto nudo solo quando non hai bisogno di metadati e puoi accettare che aggiungere campi in seguito cambi il contratto.

Perché un'API non dovrebbe mai restituire 200 per ogni esito?

CDN, gateway, circuit breaker, politiche di retry e dashboard leggono tutti lo stato HTTP per decidere se fare cache, retry o alert. Con 200 ovunque trattano i fallimenti come successi, e ogni alert richiede un parsing personalizzato del codice di business.

Gli endpoint di elenco devono portare metadati di paginazione?

Sì. Senza total o un cursore non c'è paginatore, e le liste vuote devono restituire [] invece di null, altrimenti la chiamata .map del frontend si rompe.

Ulteriori letture