API codici di errore e best practices
1) Perché standardizzare gli errori
Prevedibilità per i clienti: formato unico e comportamento dei retrai.
Accelerazione di debag: «trace _ id »/« sollest _ id», stabili «error _ code».
Sicurezza: SQL/stack traces/confighi non scompaiono.
Osservabilità: segnalazione della tassonomia degli errori (validazione, quote, timeout, ecc.).
2) Principi di base
1. Un unico formato di risposta per tutti i 4xx/5xx (e 2xx con errori parziali - uno schema separato).
2. Semantico chiaro HTTP: il giusto stato è più importante.
3. I due livelli di codice sono il trasporto ('status') e lo stabile di dominio «error _ code».
4. Retriable vs Non-retriable: indicare chiaramente e dare un suggerimento sul back-off.
5. Protezione predefinita: dettagli solo per il client con permessi; Niente piste interne.
6. Localizzazione: il codice automatico rimane stabile e il testo viene tradotto.
3) Unico formato di errore (basato su RFC 7807)
JSON consigliato (esteso «application/perfem + json»):json
{
"type": "https://api. example. com/errors/validation_failed",
"title": "Validation failed",
"status": 422,
"error_code": "VAL_001",
"detail": "Field 'email' must be a valid address",
"instance": "req_01HZY...93",
"trace_id": "a1b2c3d4e5f6",
"retriable": false,
"errors": [
{"field": "email", "code": "email_invalid", "message": "Invalid email"}
],
"hint": "Fix payload and retry",
"meta": {"docs": "https://docs. example. com/errors#VAL_001"}
}
Obbligatori: 'type', 'title', 'status', 'errore _ code', 'trace _ id'.
Opzionale: «errors []», «retriable», «hint», «meta».
- `Content-Type: application/problem+json`
- `X-Request-ID`/`Traceparent` (W3C)
- (per 429/503) 'Retry-After' (secondi o data)
4) Semantica HTTP states (fusione classica e pratica)
2xx (successo con sfumature)
200 OK è un successo normale.
201 Created - È stata creata una risorsa.
202 Accetted - asincrona in coda (date'status _ url ').
207 Multi-Status è un successo parziale (evitare, se possibile).
4xx (errore client)
400 Bad Recest - sintassi/formato, ma non convalidazione dei campi (migliore di 422).
401 Unauthorized - no/token non valido. Avanti «WWW-Authenticate».
403 Forbidden - il token è valida, ma mancano i diritti (RBAC/ABAC/limiti).
404 Not Found - risorsa/endpoint non disponibile.
409 Conflict - conflitto di versioni/stato (ottimistico locking, idempotency).
410 Gone - endpoint rimosso per sempre.
412 Precision Failed - ETag/If-Match non è passata.
415 Unsupported Media Type - «Content-Type» non valido.
422 Unprocessable Entity - convalida delle regole aziendali.
429 Too Many Recests - Superate le quote/velocità (vedi l'articolo 7).
5xx (errore del server)
500 Internal Server Errore: errore improvviso Non rivelare i dettagli.
502 Bad Gateway - Errore upstream.
503 Service Unavailable - degrado/sovraccarico, date'Retry-After '.
504 Gateway Timeout - timeout backend.
5) Tassonomia domeni'error _ code'
Consigliamo intervalli:- «AUTH _» - Autenticazione/autorizzazione.
- «VAL _» - convalida i dati di input.
- «RATELIMIT _» - Quote e velocità.
- «IDAMP _» è idempotenza/duplicati.
- «CONFLICT _» - versioni/stato.
- «DEP _» - Dipendenze (PSP/DNS/SMTP).
- PAY _ è un errore di business del dominio dei pagamenti.
- SEC _ - Sicurezza (firme, HMAC, mTLS).
- «INT _» è interno improvviso.
- Stabilità nel tempo (back-compat).
- Descrizioni e esempi nella directory degli errori (docs + machine-readable JSON).
6) Retriable vs Non-retriable
Campi:- `retriable: true|false`
- Se «true» è obbligatorio «Retry-After» (in secondi) o «back-off esponenziale (a partire da 1-2 c, max 30-60 s)».
Retriable è solitamente «502/503/504», alcuni «500», «429» (dopo la finestra).
Non-retriable: `400/401/403/404/409/410/415/422`.
7) Rate limit & quote errore (429)
Corpo:json
{
"type": "https://api. example. com/errors/rate_limited",
"title": "Rate limit exceeded",
"status": 429,
"error_code": "RATELIMIT_RPS",
"detail": "Too many requests",
"retriable": true
}
Intestazioni:
- `Retry-After: 12`
- `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`
- Для квот: `X-Quota-Limit`, `X-Quota-Remaining`, `X-Quota-Reset`
8) Idampotenza e conflitti
Le richieste di scrittura sono «Idempotency-Key» (univoca tra 24 e 72 ore).
Conflitto di ripetizione → 409 Conflict con'errore _ code: "IDAMP _ REPLAY" ".
Conflitto tra le versioni della risorsa ETAG 412 Precisition Failed.
Nella risposta, allegare «resource _ id »/« status _ url» per una nuova richiesta sicura.
9) Validazione e 422
Restituisci l'elenco degli errori nei campi:json
{
"status": 422,
"error_code": "VAL_001",
"errors": [
{"field":"email","code":"email_invalid","message":"Invalid email"},
{"field":"age","code":"min","message":"Must be >= 18"}
]
}
Regole:
- Non duplicate lo stesso in 400-422 preferiti per la validazione aziendale.
- I messaggi sono umani; «code» è automatico.
10) Sicurezza degli errori
Mai: stack traces, SQL, percorsi file, nomi privati host.
Modificare il PII; tieni d'occhio GDPR/DSAR.
Per firma/NMAS: Distingui «SEC _ SIGNATURE _ MISMATCH» (403) da «SEC _ TIMESTAMP _ SKEW» (401/403) con il suggerimento «controlla l'ora di © 5 minuti».
11) Correlazione e osservazione
Aggiungi sempre «trace _ id »/« X-Sollest-ID» e scorri nelle piste.
Aggregare gli errori in «error _ code» e «status» in «top errori», «new vs known».
Alert: picco 5xx/422/429, latitanza p95, share of errors.
12) gRPC/GraphQL/Webhooks - mapping
gRPC ↔ HTTP
GraphQL
Trasporti 200, ma 'errors []' dentro - aggiunge'estensioni. code` и `trace_id`.
Per «fatal» (autenticazione/quote) è meglio un vero HTTP.
Webhooks
Solo 2xx destinatario ha avuto successo.
Retrai con back off esponenziale, 'X-Webhook-ID', 'X-Firma'.
410 dal destinatario - Interrompere i retrai (endpoint rimosso).
13) Versioning degli errori
«type »/« error _ code» è stabile; i nuovi sono solo aggiungerli.
Se si modifica lo schema del corpo, aumentare la versione minore dell'API o dì problem + json; v=2`.
Documentazione: tabella codici + esempi; changelog errori.
14) Documentazione (frammenti)
Risposte globali
yaml components:
responses:
Problem:
description: Problem Details content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
schemas:
Problem:
type: object required: [type, title, status, error_code, trace_id]
properties:
type: { type: string, format: uri }
title: { type: string }
status: { type: integer }
error_code: { type: string }
detail: { type: string }
instance: { type: string }
trace_id: { type: string }
retriable: { type: boolean }
errors:
type: array items:
type: object properties:
field: { type: string }
code: { type: string }
message: { type: string }
Esempio di endpoint
yaml paths:
/v1/users:
post:
responses:
'201': { description: Created }
'401': { $ref: '#/components/responses/Problem' }
'422': { $ref: '#/components/responses/Problem' }
'429': { $ref: '#/components/responses/Problem' }
'500': { $ref: '#/components/responses/Problem' }
15) Test e qualità
Il contratto-test è compatibile con l'applicazione/problem + json, campi obbligatori.
Negative test: tutti i rami 401/403/404/ 409/422/429/500.
Chaos/latency - Controllo dei retrai su 5xx/ 503/504/429 («Retry-After»).
Sicurezza test: nessun messaggio interno, maschera PII corretta.
Backward-compat: i vecchi client comprendono i nuovi campi (aggiungi, non rompi).
16) Assegno-foglio di implementazione
- Unico'profem + json '+ stabile'err'code'.
- Semantica corretta HTTP/gRPC/GraphQL.
- Retriable/no-retriable + «Retry-After »/linee guida del back-off.
- Titoli rate-limit e 429 comportamenti.
- Idempotenza ('Idempotency-Key', 409/412).
- Sicurezza: senza stack traces/segreti, redazione PII.
- 'trace _ id '/' X-Sollest-ID' in tutti gli errori.
- Documentazione della directory di errori e esempi.
- Monitoraggio della tassonomia degli errori.
- Autostop di script negativi.
17) Mini FAQ
Qual è la differenza tra 400 e 422?
400 è una query rotta (sintassi/tipo di contenuto). 422 è valida per sintassi, ma le regole aziendali non sono passate.
Quando il 401 e il 403?
401 - no/token non valido 403 - Il token c'è, manca la patente.
È sempre necessario «Retry-After»?
Per 429/503 sì; Per gli altri retriable, è consigliabile fare una raccomandazione esplicita.
Totale
Gli errori ben progettati sono un contratto: uno stato HTTP corretto, un unico «problem + json», uno stabile «error _ code», suggerimenti espliciti sui retrai e una sicurezza rigorosa. Standardizzare il formato, documentare la tassonomia, aggiungere telemetria e test e rendere l'API prevedibile, sicura e amichevole con gli integratori.