ℹ️

RFC9457のメモ

に公開

TL;DR

ツイッターでこういう話があり、興味があったので調べました。
https://x.com/tmknom/status/1983069283682001160

このRFCは草案段階なので従うかどうかは自由と考えますが、エラー時のフォーマットの標準と指針、特に複数のエラーを含むパターンの指針があるのはよさそうに思います。
既存アプリケーションのエラーを置き換える必要はなさそう(ドキュメント中でも置き換えるべきものでないと記述あり)ですが、方針が決まらず困っているなら参考にはなりそうです。

RFC9457の概要

https://www.rfc-editor.org/rfc/rfc9457.html

基本的には、HTTPステータスコードが200以外のとき、レスポンスボディをどうするかの指針を提示するものという認識です。

2016年にRFC7807 (https://www.rfc-editor.org/rfc/rfc7807) というのがあり、そこでエラー時にJSONまたはXMLで返すこと、そこに含まれる標準フィールドと、何を返すとよいかが定義されていました。

RFC7807を置き換えるのがRFC9457となっており、主な変更点は以下です。

  1. 同一のエラーが複数発生した場合のエラーの返し方の指針の追加
  2. 異なるエラーが発生したときの指針の追加
  3. typeフィールドの指針の追加
  4. typeでURLを返すときのレジストリの利用について追加

ざっくりどういうレスポンスを返すべきか

例示されているのは利用クレジット不足のパターンで、こういうレスポンスになります。
リクエストヘッダのAcceptでJSON、XMLどちらで返すか決めるのがよいようです。

JSON 形式のレスポンス例

HTTP 応答ヘッダー

HTTP/1.1 403 Forbidden
Content-Type: application/problem+json
Content-Language: en

応答ボディ (application/problem+json)

{
 "type": "https://example.com/probs/out-of-credit",
 "status": 403,
 "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"]
}

typeフィールドはHTTPステータスを更に細分化し、説明や解決方法が書かれたURLを返すことが想定されているようです。エラーの説明がHTTPステータスで事足りる場合は about:blank または空としてよいとのこと。
例えばSwaggerHubを運営しているSmart Bearがエラーごとのドキュメントを公開していたりします。

複数のエラーメッセージを含むエラー

errorsフィールドを配列で持つとよいのではないかと書かれています。
例えばバリデーションエラーの例として以下が提示されています。

{
  "type": "https://example.net/validation-error",
  "title": "Your request is invalid.",
  "status": 422,
  "errors": [
    {
      "detail": "must be a positive integer",
      "pointer": "#/age"
    },
    {
      "detail": "must be 'green', 'red' or 'blue'",
      "pointer": "#/profile/color"
    }
  ]
}

ただし、errorsフィールドは拡張フィールドであり、標準として提案されているものではないようです。
上記のバリデーションエラーのようなものはドメイン特有のものであって標準にしないほうが適切という思想のようでした。

また異なるエラー(HTTPステータスまたはTypeが異なる)が複数ある場合は、重要なものを優先して返すことが提案されています。

typeのレジストリ

細分化したエラーを登録するグローバルなレジストリとして以下が提案されています。が、現在のところほとんど登録されていないようです。充実したら嬉しいのであろうか…。
https://www.iana.org/assignments/http-problem-types/http-problem-types.xhtml

巨大なサービスで多数のチームがいてサービスがAPI群で構成されているとか、外部APIとして公開しているのであれば、typeでドキュメントに飛ぶのは嬉しいかもしれません。

付記:RFC9457の実際の取組みについて

ざっと探した範囲では、取り組みを公言している国内事例はなさそうでした。
ウェブ上の感想を見る感じ、外に出ない取り組みとしては行われていそうではあります。

フレームワークとかプロダクトごとに対応されているという情報は確認できました(Spring Bootなど)

godだとchiにサードパーティーのミドルウェアがあったり、HumaというフレームワークでRFC9457に準拠したエラーを返せたりするみたいです。

OpenAPI 3.0からはレスポンスの型として content: application/problem+json が使用可能になっています。ただし型定義はされていません。
swagger.ioのこの辺に定義があるのでそちらを参考にするとよさそうです。
https://swagger.io/blog/problem-details-rfc9457-api-error-handling/
https://api.swaggerhub.com/domains/smartbear-public/ProblemDetails/1.0.0#/components/responses/ServiceUnavailable

SwaggerHubを運営しているSmartBearではエラー一覧をgithubで管理してるみたいなので、OpenなAPIならそういう手段も良いかもと思いました。

株式会社エスマット

Discussion