3. The Problem Details JSON Object (L'oggetto JSON dei dettagli del problema)
Il modello canonico per i dettagli del problema è un oggetto JSON [JSON]. Quando serializzato in un documento JSON, questo formato è identificato con il tipo di media "application/problem+json".
Ad esempio:
POST /purchase HTTP/1.1
Host: store.example.com
Content-Type: application/json
Accept: application/json, application/problem+json
{
"item": 123456,
"quantity": 2
}
HTTP/1.1 403 Forbidden
Content-Type: application/problem+json
Content-Language: en
{
"type": "https://example.com/probs/out-of-credit",
"title": "You do not have enough credit.",
"detail": "Your current balance is 30, but that costs 50.",
"instance": "/account/12345/msgs/abc",
"balance": 30,
"accounts": ["/account/12345",
"/account/67890"]
}
Qui, il problema out-of-credit (identificato dal suo tipo) indica il motivo del 403 in "title", identifica l'occorrenza specifica del problema con "instance", fornisce dettagli specifici dell'occorrenza in "detail" e aggiunge due estensioni: "balance" trasmette il saldo del conto e "accounts" elenca i link dove il conto può essere ricaricato.
Quando progettate per accoglierlo, le estensioni specifiche del problema possono trasmettere più di un'istanza dello stesso tipo di problema. Ad esempio:
POST /details HTTP/1.1
Host: account.example.com
Accept: application/json
{
"age": 42.3,
"profile": {
"color": "yellow"
}
}
HTTP/1.1 422 Unprocessable Content
Content-Type: application/problem+json
Content-Language: en
{
"type": "https://example.net/validation-error",
"title": "Your request is not valid.",
"errors": [
{
"detail": "must be a positive integer",
"pointer": "#/age"
},
{
"detail": "must be 'green', 'red' or 'blue'",
"pointer": "#/profile/color"
}
]
}
Il tipo di problema fittizio qui definisce l'estensione "errors", un array che descrive i dettagli di ogni errore di validazione. Ogni membro è un oggetto contenente "detail" per descrivere il problema e "pointer" per localizzare il problema all'interno del contenuto della richiesta utilizzando un JSON Pointer [JSON-POINTER].
Quando un'API incontra più problemi che non condividono lo stesso tipo, è RACCOMANDATO che il problema più rilevante o urgente sia rappresentato nella risposta. Sebbene sia possibile creare tipi di problema "batch" generici che trasmettono tipi disparati multipli, non si adattano bene alla semantica HTTP.
Si noti anche che l'API ha risposto con il tipo "application/problem+json", anche se il client non l'ha elencato in Accept, come consentito da HTTP (vedere sezione 12.5.1 di [HTTP]).
3.1. Members of a Problem Details Object (Membri di un oggetto di dettagli del problema)
Gli oggetti di dettagli del problema possono avere i seguenti membri. Se il tipo di valore di un membro non corrisponde al tipo specificato, il membro DEVE essere ignorato -- cioè, l'elaborazione continuerà come se il membro non fosse stato presente.
3.1.1. "type"
Il membro "type" è una stringa JSON contenente un riferimento URI [URI] che identifica il tipo di problema. I consumatori DEVONO utilizzare l'URI "type" (dopo la risoluzione, se necessario) come identificatore primario del tipo di problema.
Quando questo membro non è presente, il suo valore è assunto essere "about:blank".
Se l'URI di tipo è un locator (ad es., quelli con uno schema "http" o "https"), dereferenziarlo DOVREBBE fornire documentazione leggibile dall'uomo per il tipo di problema (ad es., utilizzando HTML [HTML5]). Tuttavia, i consumatori NON DOVREBBERO dereferenziare automaticamente l'URI di tipo, a meno che non lo facciano quando forniscono informazioni agli sviluppatori (ad es., quando viene utilizzato uno strumento di debug).
Quando "type" contiene un URI relativo, viene risolto rispetto all'URI base del documento, secondo [URI], sezione 5. Tuttavia, l'uso di URI relativi può causare confusione e potrebbero non essere gestiti correttamente da tutte le implementazioni.
Ad esempio, se le due risorse "https://api.example.org/foo/bar/123" e "https://api.example.org/widget/456" rispondono entrambe con un "type" uguale al riferimento URI relativo "example-problem", quando risolti identificheranno risorse diverse ("https://api.example.org/foo/bar/example-problem" e "https://api.example.org/widget/example-problem", rispettivamente). Pertanto, è RACCOMANDATO utilizzare URI assoluti in "type" quando possibile e che quando vengono utilizzati URI relativi, includano il percorso completo (ad es., "/types/123").
L'URI di tipo può essere un URI non risolvibile. Ad esempio, lo schema URI tag [TAG] può essere utilizzato per identificare in modo univoco i tipi di problema:
tag:[email protected],2021-09-17:OutOfLuck
Tuttavia, gli URI di tipo risolvibili sono incoraggiati da questa specifica perché potrebbe diventare desiderabile risolvere l'URI in futuro. Ad esempio, se un progettista di API utilizzasse l'URI sopra e successivamente adottasse uno strumento che risolve gli URI di tipo per scoprire informazioni sull'errore, sfruttare tale capacità richiederebbe il passaggio a un URI risolvibile, creando una nuova identità per il tipo di problema e introducendo quindi un cambiamento breaking.
3.1.2. "status"
Il membro "status" è un numero JSON che indica il codice di stato HTTP (sezione 15 di [HTTP]) generato dal server di origine per questa occorrenza del problema.
Il membro "status", se presente, è solo consultivo; trasmette il codice di stato HTTP utilizzato per comodità del consumatore. I generatori DEVONO utilizzare lo stesso codice di stato nella risposta HTTP effettiva, per assicurare che il software HTTP generico che non comprende questo formato si comporti ancora correttamente. Vedere sezione 5 per ulteriori avvertenze riguardo al suo uso.
I consumatori possono utilizzare il membro status per determinare quale codice di stato originale è stato utilizzato dal generatore quando è stato modificato (ad es., da un intermediario o cache) e quando il contenuto di un messaggio persiste senza informazioni HTTP. Il software HTTP generico utilizzerà comunque il codice di stato HTTP.
3.1.3. "title"
Il membro "title" è una stringa JSON contenente un breve riepilogo leggibile dall'uomo del tipo di problema.
NON DOVREBBE cambiare da un'occorrenza all'altra del problema, tranne per la localizzazione (ad es., utilizzando la negoziazione proattiva del contenuto; vedere sezione 12.1 di [HTTP]).
La stringa "title" è consultiva ed è inclusa solo per gli utenti che non sono a conoscenza e non possono scoprire la semantica dell'URI di tipo (ad es., durante l'analisi dei log offline).
3.1.4. "detail"
Il membro "detail" è una stringa JSON contenente una spiegazione leggibile dall'uomo specifica per questa occorrenza del problema.
La stringa "detail", se presente, dovrebbe concentrarsi sull'aiutare il client a correggere il problema, piuttosto che fornire informazioni di debug.
I consumatori NON DOVREBBERO analizzare il membro "detail" per informazioni; le estensioni sono modi più appropriati e meno soggetti a errori per ottenere tali informazioni.
3.1.5. "instance"
Il membro "instance" è una stringa JSON contenente un riferimento URI che identifica l'occorrenza specifica del problema.
Quando l'URI "instance" è dereferenziabile, l'oggetto di dettagli del problema può essere recuperato da esso. Potrebbe anche restituire informazioni sull'occorrenza del problema in altri formati attraverso l'uso della negoziazione proattiva del contenuto (vedere sezione 12.5.1 di [HTTP]).
Quando l'URI "instance" non è dereferenziabile, serve come identificatore univoco per l'occorrenza del problema che può essere di significato per il server ma è opaco per il client.
Quando "instance" contiene un URI relativo, viene risolto rispetto all'URI base del documento, secondo [URI], sezione 5. Tuttavia, l'uso di URI relativi può causare confusione e potrebbero non essere gestiti correttamente da tutte le implementazioni.
Ad esempio, se le due risorse "https://api.example.org/foo/bar/123" e "https://api.example.org/widget/456" rispondono entrambe con un'"instance" uguale al riferimento URI relativo "example-instance", quando risolte identificheranno risorse diverse ("https://api.example.org/foo/bar/example-instance" e "https://api.example.org/widget/example-instance", rispettivamente). Pertanto, è RACCOMANDATO utilizzare URI assoluti in "instance" quando possibile e che quando vengono utilizzati URI relativi, includano il percorso completo (ad es., "/instances/123").
3.2. Extension Members (Membri di estensione)
Le definizioni dei tipi di problema POSSONO estendere l'oggetto di dettagli del problema con membri aggiuntivi che sono specifici per quel tipo di problema.
Ad esempio, il nostro problema out-of-credit sopra definisce due tali estensioni -- "balance" e "accounts" per trasmettere informazioni aggiuntive specifiche del problema.
Allo stesso modo, l'esempio "validation error" definisce un'estensione "errors" che contiene un elenco di singole occorrenze di errore trovate, con dettagli e un puntatore alla posizione di ciascuna.
I client che consumano dettagli del problema DEVONO ignorare tutte le estensioni che non riconoscono; ciò consente ai tipi di problema di evolversi e includere informazioni aggiuntive in futuro.
Quando si creano estensioni, gli autori dei tipi di problema dovrebbero scegliere i loro nomi con attenzione. Per essere utilizzati nel formato XML (vedere appendice B), dovranno conformarsi alla regola Name nella sezione 2.3 di [XML].