HTTP APIの構造化エラーメッセージ

Nicolas Fränkel

Nicolas Fränkel

November 2, 2022

Technology

Apache APISIXプロジェクトに取り組み始めて以来、私はREST RESTful HTTP APIに関する知識と理解を深めようと努めてきました。そのために、以下の情報源を読んだり視聴したりしています:

  • 書籍。現在、API Design Patternsを読み終えようとしています。近々レビューを書く予定です。
  • YouTube。ErikWildeのチャンネルをお勧めします。すべての動画がAPIに焦点を当てており、いくつかの動画は特に優れています。
  • IETF RFC。ほとんどのRFCはAPIに関するものではありませんが、親切な方がAPI関連のRFCリストをまとめてくれています。

今日は、「HTTP APIのための問題詳細」RFC、別名RFC 7807を紹介したいと思います。

問題点

RESTの原則では、HTTPステータスを使用して通信することが求められています。エラーの場合、HTTPは2つの範囲を定義しています:クライアントエラー(4xx)とサーバーエラー(5xx)です。

例えば、銀行のAPIで口座間の送金を行う場合、残高以上の送金を試みると失敗するはずです。いくつかのHTTPステータスコードが該当します:

  • 400 Bad Request:クライアントエラーと見なされる何かが原因で、サーバーがリクエストを処理できない、または処理しない。
  • 402 Payment Required:クライアントが支払いを行うまでリクエストを処理できない。ただし、標準的な使用慣習はなく、異なるエンティティが他の文脈で使用しています。
  • 409 Conflict:リクエストがターゲットリソースの現在の状態と競合する。

ここで最初の問題が発生します:HTTPステータスコードは、ブラウザを介した人間と機械の相互作用のために指定されており、APIを介した機械間の相互作用のために設計されていません。そのため、ユースケースに1対1で対応するステータスコードを選択することは稀です。参考までに、Martin Fowlerはこのケースで409を推奨しているようです

ステータスコードが何であれ、2つ目の問題はエラーペイロード、より正確にはその構造に関するものです。クライアントとAPIプロバイダーが単一の組織で管理されている場合、構造は重要ではありません。たとえそれぞれが専任のチームによって開発されていたとしても、彼らは調整することができます。例えば、独自のAPIを呼び出すモバイルアプリを想像してください。

しかし、チームがサードパーティのAPIを使用することを決定した場合、レスポンス構造の選択は重要です。なぜなら、それは契約の一部と見なされるため、プロバイダーからの変更がクライアントを壊す可能性があるからです。さらに悪いことに、構造はプロバイダーごとに異なる可能性があります。

したがって、標準化されたエラー報告構造は以下の利点があります:

  • プロバイダー間で統一性を提供する
  • APIの安定性を向上させる

RFC 7807

RFC 7807は、標準化されたエラー構造を提供することでこの問題を解決することを目指しています。

構造は以下の通りです:

構造

RFCはフィールドについて説明しています:

  • "type" (string) - 問題のタイプを識別するURI参照[RFC3986]。この仕様では、参照解除時に問題タイプの人間が読めるドキュメントを提供することを推奨しています(例:HTML [W3C.REC-html5-20141028]を使用)。このメンバーが存在しない場合、その値は"about:blank"と見なされます。
  • "title" (string) - 問題タイプの短い人間が読める要約。問題の発生ごとに変更すべきではありませんが、ローカライゼーションの目的(例:プロアクティブなコンテンツネゴシエーションを使用;[RFC7231, Section 3.4]を参照)を除きます。
  • "status" (number) - この問題の発生に対してオリジンサーバーが生成した([RFC7231], Section 6)HTTPステータスコード。
  • "detail" (string) - この問題の発生に特化した人間が読める説明。
  • "instance" (string) - 問題の特定の発生を識別するURI参照。参照解除時にさらに情報が得られる場合と得られない場合があります。

-- 問題詳細オブジェクトのメンバー

RFCは、銀行送金に十分な資金がない場合のサンプルを提供しています。

RFC例

私の既存のデモを例として使用します。このデモは、APIの進化を容易にするためのいくつかのステップを強調しています。

ステップ6では、ユーザーに登録を促すため、認証されていない場合に時間枠内の呼び出し回数を制限します。これのために専用のApache APISIXプラグインを作成しました。呼び出し回数が制限に達した後、以下のレスポンスを返します:

HTTP/1.1 429 Too Many Requests
Date: Fri, 28 Oct 2022 11:56:11 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/2.15.0

{"error_msg":"Please register at https:\/\/apisix.org\/register to get your API token and enjoy unlimited calls"}

RFC 7807に従ってメッセージを構造化してみましょう。

RFC 7807ルール

結論

RFC 7807は、クライアント開発者だけでなく、API実装者にとっても大きな助けとなります。なぜなら、各プロジェクトで車輪の再発明を避けるための迅速なガイドラインを提供するからです。

さらに進む:

2022年10月30日にA Java Geekで最初に公開されました

Tags: