Zum Hauptinhalt springen

3. The Problem Details JSON Object (Das Problem Details JSON-Objekt)

Das kanonische Modell für Problemdetails ist ein JSON [JSON]-Objekt. Wenn es in einem JSON-Dokument serialisiert wird, wird dieses Format mit dem Medientyp "application/problem+json" identifiziert.

Zum Beispiel:

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"]
}

Hier gibt das out-of-credit-Problem (identifiziert durch seinen Typ) den Grund für den 403 in "title" an, identifiziert das spezifische Problemauftreten mit "instance", gibt auftretensspezifische Details in "detail" an und fügt zwei Erweiterungen hinzu: "balance" übermittelt den Kontostand, und "accounts" listet Links auf, wo das Konto aufgeladen werden kann.

Wenn sie dafür ausgelegt sind, können problemspezifische Erweiterungen mehr als eine Instanz desselben Problemtyps übermitteln. Zum Beispiel:

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"
}
]
}

Der fiktive Problemtyp hier definiert die Erweiterung "errors", ein Array, das die Details jedes Validierungsfehlers beschreibt. Jedes Mitglied ist ein Objekt, das "detail" enthält, um das Problem zu beschreiben, und "pointer", um das Problem innerhalb des Inhalts der Anfrage mit einem JSON Pointer [JSON-POINTER] zu lokalisieren.

Wenn eine API auf mehrere Probleme trifft, die nicht denselben Typ teilen, wird EMPFOHLEN, dass das relevanteste oder dringendste Problem in der Antwort dargestellt wird. Obwohl es möglich ist, generische "Batch"-Problemtypen zu erstellen, die mehrere unterschiedliche Typen übermitteln, passen sie nicht gut in die HTTP-Semantik.

Beachten Sie auch, dass die API mit dem Typ "application/problem+json" geantwortet hat, obwohl der Client ihn nicht in Accept aufgeführt hat, wie es von HTTP erlaubt ist (siehe Abschnitt 12.5.1 von [HTTP]).

3.1. Members of a Problem Details Object (Mitglieder eines Problem Details-Objekts)

Problem Details-Objekte können die folgenden Mitglieder haben. Wenn der Werttyp eines Mitglieds nicht mit dem angegebenen Typ übereinstimmt, MUSS das Mitglied ignoriert werden -- d.h., die Verarbeitung wird fortgesetzt, als ob das Mitglied nicht vorhanden gewesen wäre.

3.1.1. "type"

Das Mitglied "type" ist eine JSON-Zeichenfolge, die eine URI-Referenz [URI] enthält, die den Problemtyp identifiziert. Verbraucher MÜSSEN die "type"-URI (nach Auflösung, falls erforderlich) als primären Identifikator des Problemtyps verwenden.

Wenn dieses Mitglied nicht vorhanden ist, wird sein Wert als "about:blank" angenommen.

Wenn die Typ-URI ein Locator ist (z.B. solche mit einem "http"- oder "https"-Schema), SOLLTE das Dereferenzieren menschenlesbare Dokumentation für den Problemtyp bereitstellen (z.B. unter Verwendung von HTML [HTML5]). Verbraucher SOLLTEN jedoch die Typ-URI NICHT automatisch dereferenzieren, es sei denn, sie tun dies, wenn sie Entwicklern Informationen bereitstellen (z.B. wenn ein Debugging-Tool verwendet wird).

Wenn "type" eine relative URI enthält, wird sie relativ zur Basis-URI des Dokuments aufgelöst, gemäß [URI], Abschnitt 5. Die Verwendung relativer URIs kann jedoch zu Verwirrung führen, und sie werden möglicherweise nicht von allen Implementierungen korrekt behandelt.

Wenn beispielsweise die beiden Ressourcen "https://api.example.org/foo/bar/123" und "https://api.example.org/widget/456" beide mit einem "type" antworten, der der relativen URI-Referenz "example-problem" entspricht, identifizieren sie bei Auflösung unterschiedliche Ressourcen ("https://api.example.org/foo/bar/example-problem" bzw. "https://api.example.org/widget/example-problem"). Daher wird EMPFOHLEN, absolute URIs in "type" zu verwenden, wenn möglich, und wenn relative URIs verwendet werden, den vollständigen Pfad einzuschließen (z.B. "/types/123").

Die Typ-URI darf eine nicht auflösbare URI sein. Beispielsweise kann das Tag-URI-Schema [TAG] verwendet werden, um Problemtypen eindeutig zu identifizieren:

tag:[email protected],2021-09-17:OutOfLuck

Auflösbare Typ-URIs werden jedoch von dieser Spezifikation empfohlen, da es wünschenswert werden könnte, die URI in Zukunft aufzulösen. Wenn beispielsweise ein API-Designer die obige URI verwendet und später ein Tool einführt, das Typ-URIs auflöst, um Informationen über den Fehler zu ermitteln, würde die Nutzung dieser Fähigkeit den Wechsel zu einer auflösbaren URI erfordern, wodurch eine neue Identität für den Problemtyp geschaffen und somit eine breaking Änderung eingeführt würde.

3.1.2. "status"

Das Mitglied "status" ist eine JSON-Zahl, die den HTTP-Statuscode (Abschnitt 15 von [HTTP]) angibt, der vom Ursprungsserver für dieses Auftreten des Problems generiert wurde.

Das Mitglied "status" ist, falls vorhanden, nur beratend; es übermittelt den verwendeten HTTP-Statuscode zur Bequemlichkeit des Verbrauchers. Generatoren MÜSSEN denselben Statuscode in der tatsächlichen HTTP-Antwort verwenden, um sicherzustellen, dass generische HTTP-Software, die dieses Format nicht versteht, sich weiterhin korrekt verhält. Siehe Abschnitt 5 für weitere Einschränkungen bezüglich seiner Verwendung.

Verbraucher können das status-Mitglied verwenden, um zu bestimmen, welcher ursprüngliche Statuscode vom Generator verwendet wurde, wenn er geändert wurde (z.B. durch einen Vermittler oder Cache) und wenn der Inhalt einer Nachricht ohne HTTP-Informationen persistiert wird. Generische HTTP-Software verwendet weiterhin den HTTP-Statuscode.

3.1.3. "title"

Das Mitglied "title" ist eine JSON-Zeichenfolge, die eine kurze, menschenlesbare Zusammenfassung des Problemtyps enthält.

Es SOLLTE sich NICHT von einem Auftreten des Problems zum anderen ändern, außer zur Lokalisierung (z.B. unter Verwendung proaktiver Inhaltsverhandlung; siehe Abschnitt 12.1 von [HTTP]).

Die "title"-Zeichenfolge ist beratend und wird nur für Benutzer eingefügt, die die Semantik der Typ-URI nicht kennen und nicht entdecken können (z.B. während der Offline-Protokollanalyse).

3.1.4. "detail"

Das Mitglied "detail" ist eine JSON-Zeichenfolge, die eine menschenlesbare Erklärung enthält, die spezifisch für dieses Auftreten des Problems ist.

Die "detail"-Zeichenfolge sollte sich, falls vorhanden, darauf konzentrieren, dem Client bei der Behebung des Problems zu helfen, anstatt Debugging-Informationen zu geben.

Verbraucher SOLLTEN das "detail"-Mitglied NICHT nach Informationen parsen; Erweiterungen sind geeignetere und weniger fehleranfällige Wege, solche Informationen zu erhalten.

3.1.5. "instance"

Das Mitglied "instance" ist eine JSON-Zeichenfolge, die eine URI-Referenz enthält, die das spezifische Auftreten des Problems identifiziert.

Wenn die "instance"-URI dereferenzierbar ist, kann das Problem Details-Objekt daraus abgerufen werden. Es könnte auch Informationen über das Problemauftreten in anderen Formaten durch die Verwendung proaktiver Inhaltsverhandlung zurückgeben (siehe Abschnitt 12.5.1 von [HTTP]).

Wenn die "instance"-URI nicht dereferenzierbar ist, dient sie als eindeutiger Identifikator für das Problemauftreten, der für den Server von Bedeutung sein kann, aber für den Client undurchsichtig ist.

Wenn "instance" eine relative URI enthält, wird sie relativ zur Basis-URI des Dokuments aufgelöst, gemäß [URI], Abschnitt 5. Die Verwendung relativer URIs kann jedoch zu Verwirrung führen, und sie werden möglicherweise nicht von allen Implementierungen korrekt behandelt.

Wenn beispielsweise die beiden Ressourcen "https://api.example.org/foo/bar/123" und "https://api.example.org/widget/456" beide mit einer "instance" antworten, die der relativen URI-Referenz "example-instance" entspricht, identifizieren sie bei Auflösung unterschiedliche Ressourcen ("https://api.example.org/foo/bar/example-instance" bzw. "https://api.example.org/widget/example-instance"). Daher wird EMPFOHLEN, absolute URIs in "instance" zu verwenden, wenn möglich, und wenn relative URIs verwendet werden, den vollständigen Pfad einzuschließen (z.B. "/instances/123").

3.2. Extension Members (Erweiterungsmitglieder)

Problemtypdefinitionen KÖNNEN das Problem Details-Objekt mit zusätzlichen Mitgliedern erweitern, die spezifisch für diesen Problemtyp sind.

Beispielsweise definiert unser out-of-credit-Problem oben zwei solche Erweiterungen -- "balance" und "accounts", um zusätzliche, problemspezifische Informationen zu übermitteln.

Ebenso definiert das "validation error"-Beispiel eine "errors"-Erweiterung, die eine Liste einzelner gefundener Fehlerauftreten enthält, mit Details und einem Zeiger auf die Position jedes einzelnen.

Clients, die Problem Details konsumieren, MÜSSEN alle solchen Erweiterungen ignorieren, die sie nicht erkennen; dies ermöglicht es Problemtypen, sich weiterzuentwickeln und in Zukunft zusätzliche Informationen einzuschließen.

Beim Erstellen von Erweiterungen sollten Problemtypautoren ihre Namen sorgfältig wählen. Um im XML-Format verwendet zu werden (siehe Anhang B), müssen sie der Name-Regel in Abschnitt 2.3 von [XML] entsprechen.