メインコンテンツまでスキップ

3. The Problem Details JSON Object (問題詳細 JSON オブジェクト)

問題詳細の正規モデルは JSON [JSON] オブジェクトです。JSON ドキュメントとしてシリアライズされる場合, そのフォーマットは "application/problem+json" メディアタイプで識別されます。

例:

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

ここで, out-of-credit 問題 (そのタイプによって識別される) は "title" で 403 の理由を示し, "instance" で特定の問題発生を識別し, "detail" で発生固有の詳細を提供し, 2 つの拡張を追加します: "balance" はアカウント残高を伝え, "accounts" はアカウントにチャージできるリンクをリストします。

それをサポートするように設計されている場合, 問題固有の拡張は同じ問題タイプの複数のインスタンスを伝達できます。例:

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

ここでの架空の問題タイプは "errors" 拡張を定義します。これは各検証エラーの詳細を記述する配列です。各メンバーは, 問題を記述する "detail" と JSON Pointer [JSON-POINTER] を使用してリクエストのコンテンツ内で問題を特定する "pointer" を含むオブジェクトです。

API が同じタイプを共有しない複数の問題に遭遇した場合, 最も関連性が高いか緊急の問題をレスポンスで表現することが推奨されます (RECOMMENDED)。複数の異なるタイプを伝達する汎用的な "バッチ" 問題タイプを作成することは可能ですが, HTTP セマンティクスにうまくマップされません。

また, API は "application/problem+json" タイプで応答していることに注意してください。これは, クライアントが Accept にリストしていなくても, HTTP で許可されています ([HTTP] のセクション 12.5.1 を参照)。

3.1. Members of a Problem Details Object (問題詳細オブジェクトのメンバー)

問題詳細オブジェクトは以下のメンバーを持つことができます。メンバーの値の型が指定された型と一致しない場合, そのメンバーは無視しなければなりません (MUST) -- つまり, メンバーが存在しなかったかのように処理が続行されます。

3.1.1. "type"

"type" メンバーは, 問題タイプを識別する URI 参照 [URI] を含む JSON 文字列です。コンシューマーは, "type" URI (必要に応じて解決後) を問題タイプの主要な識別子として使用しなければなりません (MUST)。

このメンバーが存在しない場合, その値は "about:blank" であると仮定されます。

type URI がロケーター (例: "http" または "https" スキームを持つもの) である場合, それを逆参照すると, 問題タイプの人間が読めるドキュメント (例: HTML [HTML5] を使用) を提供すべきです (SHOULD)。ただし, コンシューマーは, 開発者に情報を提供する場合 (例: デバッグツールが使用されている場合) を除き, type URI を自動的に逆参照すべきではありません (SHOULD NOT)。

"type" に相対 URI が含まれている場合, それは [URI] のセクション 5 に従って, ドキュメントのベース URI に対して相対的に解決されます。ただし, 相対 URI を使用すると混乱を招く可能性があり, すべての実装で正しく処理されない可能性があります。

例えば, 2 つのリソース "https://api.example.org/foo/bar/123""https://api.example.org/widget/456" が両方とも相対 URI 参照 "example-problem" に等しい "type" で応答する場合, 解決されると異なるリソース (それぞれ "https://api.example.org/foo/bar/example-problem""https://api.example.org/widget/example-problem") を識別します。その結果, "type" では可能な限り絶対 URI を使用することが推奨され (RECOMMENDED), 相対 URI を使用する場合は完全なパス (例: "/types/123") を含めることが推奨されます (RECOMMENDED)。

type URI は解決不可能な URI であることが許可されています。例えば, tag URI スキーム [TAG] を使用して問題タイプを一意に識別できます:

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

ただし, この仕様では解決可能な type URI が推奨されています。なぜなら, 将来 URI を解決することが望ましくなる可能性があるためです。例えば, API 設計者が上記の URI を使用し, 後でエラーに関する情報を発見するために type URI を解決するツールを採用した場合, その機能を利用するには解決可能な URI に切り替える必要があり, 問題タイプの新しいアイデンティティを作成し, 破壊的変更を導入することになります。

3.1.2. "status"

"status" メンバーは, この問題の発生に対してオリジンサーバーが生成した HTTP ステータスコード ([HTTP] のセクション 15) を示す JSON 数値です。

"status" メンバーは, 存在する場合, アドバイザリーのみです。コンシューマーの便宜のために使用される HTTP ステータスコードを伝達します。ジェネレーターは, このフォーマットを理解しない汎用 HTTP ソフトウェアが正しく動作することを保証するために, 実際の HTTP レスポンスで同じステータスコードを使用しなければなりません (MUST)。その使用に関する詳細な注意事項については, セクション 5 を参照してください。

コンシューマーは, status メンバーを使用して, ステータスコードが変更された場合 (例: 中間装置またはキャッシュによって) およびメッセージの内容が HTTP 情報なしで永続化される場合に, ジェネレーターが使用した元のステータスコードを判断できます。汎用 HTTP ソフトウェアは引き続き HTTP ステータスコードを使用します。

3.1.3. "title"

"title" メンバーは, 問題タイプの短い人間が読める要約を含む JSON 文字列です。

ローカライゼーションの目的 (例: プロアクティブなコンテンツネゴシエーションの使用。[HTTP] のセクション 12.1 を参照) を除き, 問題の発生間で変更すべきではありません (SHOULD NOT)。

"title" 文字列はアドバイザリーであり, URI のセマンティクスを認識しておらず発見できないユーザー (例: オフラインログ分析中) のためにのみ含まれています。

3.1.4. "detail"

"detail" メンバーは, この問題の発生に固有の人間が読める説明を含む JSON 文字列です。

"detail" 文字列は, 存在する場合, デバッグ情報を提供するのではなく, クライアントが問題を修正するのを支援することに焦点を当てるべきです。

コンシューマーは情報のために "detail" メンバーを解析すべきではありません (SHOULD NOT)。拡張は, そのような情報を取得するためのより適切でエラーが発生しにくい方法です。

3.1.5. "instance"

"instance" メンバーは, 問題の特定の発生を識別する URI 参照を含む JSON 文字列です。

"instance" URI が逆参照可能な場合, 問題詳細オブジェクトをそこから取得できます。プロアクティブなコンテンツネゴシエーション ([HTTP] のセクション 12.5.1 を参照) の使用を通じて, 他のフォーマットで問題発生に関する情報を返すこともあります。

"instance" URI が逆参照可能でない場合, それはサーバーにとって重要であるがクライアントにとって不透明な問題発生の一意の識別子として機能します。

"instance" に相対 URI が含まれている場合, それは [URI] のセクション 5 に従って, ドキュメントのベース URI に対して相対的に解決されます。ただし, 相対 URI を使用すると混乱を招く可能性があり, すべての実装で正しく処理されない可能性があります。

例えば, 2 つのリソース "https://api.example.org/foo/bar/123""https://api.example.org/widget/456" が両方とも相対 URI 参照 "example-instance" に等しい "instance" で応答する場合, 解決されると異なるリソース (それぞれ "https://api.example.org/foo/bar/example-instance""https://api.example.org/widget/example-instance") を識別します。その結果, "instance" では可能な限り絶対 URI を使用することが推奨され (RECOMMENDED), 相対 URI を使用する場合は完全なパス (例: "/instances/123") を含めることが推奨されます (RECOMMENDED)。

3.2. Extension Members (拡張メンバー)

問題タイプ定義は, その問題タイプに固有の追加メンバーで問題詳細オブジェクトを拡張してもかまいません (MAY)。

例えば, 上記の out-of-credit 問題は, 追加の問題固有の情報を伝達するために 2 つのそのような拡張 -- "balance" と "accounts" を定義します。

同様に, "validation error" の例は, 見つかった個々のエラー発生のリストと各エラーの詳細および場所へのポインターを含む "errors" 拡張を定義します。

問題詳細を消費するクライアントは, 認識しないそのような拡張を無視しなければなりません (MUST)。これにより, 問題タイプが進化し, 将来追加情報を含めることができます。

拡張を作成する際, 問題タイプの作成者は名前を慎重に選択すべきです。XML フォーマット (付録 B を参照) で使用するには, [XML] のセクション 2.3 の Name 規則に準拠する必要があります。