要約

  • 2016年3月のRFC 7807はHTTP APIのエラーにJSONとXMLの共通形式を定めた。機械が問題の種類を識別する第一の手掛かりはtypeのURIだった。
  • 2023年7月のRFC 9457は前規格を置き換え、相対URIの危うさ、名前の変更が生む互換性問題、複数の問題を一つの応答で扱う方法を明確にした。
  • IANAの登録簿は共通の問題型を扱う。typeが省略されたときのabout:blankは、状態コード以上の意味を主張しない。

403だけでは買い物を続けられない

HTTPの状態コードは、プロキシや一般的なクライアントに結果の大枠を伝える。403を受ければ、要求が拒まれたことは分かる。しかし商店の取引では、残高不足と別の禁止は次の行動が違う。業務上の失敗をすべて新しいHTTPコードにすれば、共通の符号体系が各社の事情で埋まってしまう。RFC 7807は、状態コードを保ちながら、応答本文に固有の問題を置く道を示した。

規格の例では、購入が403で失敗し、問題型は残高不足を示す。人向けの見出し、今回の事情を述べる説明、個別の出来事を示すinstance、残高などの拡張情報が続く。application/problem+jsonという共通の容器があっても、残高不足の具体的な意味と対処を定義するのは、そのAPIを提供する側だ。標準化団体はすべての商店の規則を代筆しなかった。

機械にとって中心になるのはtypeである。2016年の文書は、そのURIを問題型の主たる識別子として使うよう求めた。titleは人のための短い説明で、言語に応じて変わり得る。detailはその一回の失敗を説明する文章だ。文章中の単語を拾って動作を決めるクライアントは、翻訳や文面修正だけで壊れる。URIに従うクライアントは、運営者がその識別子の意味を守るという約束に依存する。

同じ応答にあるinstanceは、種類ではなく出来事を指す。二つの購入が同じ残高不足でも、問い合わせに使う個別の番号は異なる。種類で対処を決め、個別の出来事で記録を追う。この区別がなければ、同じ原因による失敗を毎回別の制度として扱う羽目になる。

何も付け足さないという設計

typeを省略したとき、値はabout:blankとみなされる。この奇妙な名前は意図的に狭い。問題にはHTTPの状態コードを超える意味がない、という宣言である。JSONに整った項目が並んでいても、403を二種類に分ける固有の約束は自然には生まれない。区別が必要なら運営者が名前を作り、説明し、保ち続けなければならない。

本文のstatusも、実際のHTTP応答の状態を置き換えない。値を含める場合は応答の状態と一致させる必要があり、一般的なHTTPソフトウェアは外側の状態を見る。本文が保存されて応答行と離れたり、中継装置で差が生じたりする場合はある。それでも共通の容器は、運んでいるプロトコルの判定権を奪わない。

名前の引っ越しは互換性の問題

RFC 9457は2023年にこの構造を引き継ぎ、住所選びの代価を具体的にした。example-problemのような相対URIは、応答の基準URLによって別の資源へ解決される。同じ文字列でも、異なる問題型になり得る。可能なら絶対URIを使うよう勧める理由はここにある。

閲覧できないURIも認められる。しかし後日、説明書を開けるURLへ変更すると、問題型の識別子そのものが変わる。古いクライアントは新しい名前を知らない。最初は些細に見えた命名が、運用を続けるうちに互換性の費用へ変わる。規格はまた、同じ検証問題に属する複数の入力ミスを拡張情報で示せる一方、異なる問題型が競う場合は最も重要または緊急な一つを示すよう勧めた。

2023年版が設けたIANAの登録簿は、広く共有できる型を対象とする。事業者固有の型はその事業者の責任に残る。実際の普及時期を知るには、日付の分かる応答とクライアントの版が要る。規格の記録だけでも、共通の形式と個別の意味を誰が負担するかは明白だ。