こんにちは!ネットワークの深淵を愛するインフラアーキテクトの私です。
皆さんは日々の開発や学習の中で、Web APIを叩いていて突然「400 Bad Request」や「500 Internal Server Error」といった冷たい数字だけのエラー画面に直面し、「おいおい、一体何がダメだったんだよ……!」と頭を抱えた経験はありませんか?
エラーが起きたとき、サーバーから返ってくる理由がバラバラだと、フロントエンドのエンジニアはエラー画面を作るだけで一苦労ですし、APIを使う側にとってもストレスですよね。
今回は、そんなWeb APIのエラー表現のモヤモヤを綺麗さっぱり解消してくれる、世界標準の仕組み「Problem Details (RFC 7807)」について、身近な例えを交えながら優しく紐解いていきたいと思います。一歩ずつ、一緒に理解していきましょう!
—
1. エラーを「郵便配達」に例えて考えてみよう
まずは、APIのやり取りを私たちの身近な「郵便配達」に例えてみましょう。
あなたが遠くにいる友人に大切な手紙を送るとします。しかし、宛先の書き方に不備があったり、切手が足りなかったりしたとき、郵便局員さんはどうするでしょうか?
- ダメなパターン: 「エラーコード:40」とだけ書かれた冷たい紙切れが1枚ポストに入っている。これでは「何がダメだったのか(住所か?切手か?名前か?)」がさっぱりわかりません。
- 良いパターン: 「宛先の番地が存在しません。正しい番地を記入して出し直してください(窓口B)」と、理由と次に取るべきアクションが丁寧に書かれた用紙が届く。
Web APIの世界もこれとまったく同じです。従来のAPIエラーは、HTTPステータスコードという「大まかな結果(成功したか、失敗したか)」しか教えてくれないことが多く、詳細な理由はサーバーの気分次第でバラバラの形式(JSONだったり、ただのHTMLだったり)で返されていました。
これでは、APIを使うクライアント側(スマホアプリやWebブラウザ)のプログラムが、エラーの内容を正確に読み取ってユーザーに優しい画面を見せるのがとても難しくなってしまいます。
—
2. 救世主「Problem Details (RFC 7807)」とは?
そこで登場するのが、RFC 7807というインターネットの標準規格で定められた「Problem Details」です。
これは一言で言うと、「エラーが起きたときの返事(JSON)の書き方を、世界中で綺麗に統一しようぜ!」という素晴らしいルールになります。
Problem Detailsを使ったエラーレスポンスには、主に以下の5つの決まった項目(フィールド)を用意します。
1. type: そのエラーが「どんな種類のトラブルか」を示すウェブページの住所(URI)
2. title: 人間が読んですぐにわかるエラーのタイトル(例:「入力値が不正です」)
3. status: HTTPステータスコード(例:400)
4. detail: 何が起きたのかを具体的に説明するメッセージ(例:「email フィールドの形式が間違っています」)
5. instance: このエラーが起きた特定の出来事を示す住所(URI)
これらが決まったフォーマットで返ってくるため、クライアント側は「どのAPIを叩いても、エラーの読み取り方はいつも同じ!」となり、開発が劇的に楽になるんです。
—
3. 実際のJSONレスポンスを見てみましょう
百聞は一見に如かず。実際にProblem Detailsに準拠したエラーのJSONデータがどのようなものか、コードブロックを見てみましょう。今回は、ユーザー登録APIでメールアドレスの形式を間違えたときの例です。
{
"type": "https://api.example.com/errors/invalid-params",
"title": "入力されたパラメータに誤りがあります",
"status": 400,
"detail": "リクエストされた 'email' フィールドの値が正しいメールアドレスの形式ではありません。",
"instance": "/users/register/err-991823"
}
どうでしょう?すごく整理されていて読みやすいですよね。
「何が起きていて(title)、なぜダメで(detail)、どのステータスなのか(status)」が一目でわかります。
さらに、この規格のすごいところは、システム固有の事情に合わせて独自の項目を自由に追加できる点です。例えば、どの入力項目でエラーが起きたのかを配列で添えてあげると、親切さがさらにアップします。
{
"type": "https://api.example.com/errors/validation-error",
"title": "バリデーションエラーが発生しました",
"status": 422,
"detail": "複数の入力項目でルール違反が見つかりました。",
"instance": "/users/register",
"invalid_params": [
{
"name": "email",
"reason": "メールアドレスの '@' が抜けています。"
},
{
"name": "age",
"reason": "年齢は0以上の整数を指定してください。"
}
]
}
このように、基本の5つのルールを守りつつ、必要に応じて現場の要件に合わせたカスタマイズができるのも、現場のエンジニアにとって非常に嬉しいポイントです。
—
4. サーバー側(バックエンド)での実装イメージ
「でも、これを作るのって難しそう……」と思われるかもしれませんが、ご安心ください。主要なプログラミング言語やフレームワークでは、このRFC 7807をサポートするライブラリや機能が最初から備わっていることが多いです。
例えば、PythonのWebフレームワークであるFastAPIや、JavaのSpring Boot、PHPのLaravelなどでも、簡単な設定やミドルウェアの追加でこのフォーマットに出力を統一できます。
Content-Type(データの種類を表す看板のようなもの)には、専用のものを指定するのがルールです。
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
この application/problem+json という看板を見て、クライアント側のプログラムは「おっ、これはRFC 7807のエラー形式だな。決まった手順で中身を読み解こう」とスムーズに処理を始めることができます。
—
5. まとめ:美しいエラー設計が強いシステムを作る
今回は、APIのエラーハンドリングを劇的に美しく、分かりやすくする「Problem Details (RFC 7807)」についてお話ししました。
- ポイントのおさらい
- エラーの内容がバラバラだと、クライアント側の開発やトラブルシューティングが大変になる。
- RFC 7807を使うことで、エラーレスポンスの形式(
type,title,status,detail,instance)を世界標準に統一できる。 application/problem+jsonという専用のContent-Typeを使い、システム間の意思疎通をスムーズにする。
インフラやネットワーク、そしてAPIの設計において、「お互いが共通のルールで会話できること」は、トラブルを防ぎ、システムを健やかに保つための最大の秘訣です。
次に新しいAPIを設計したり、エラーハンドリングを見直す機会があったら、ぜひこの「Problem Details」を思い出してみてくださいね。あなたの作るAPIが、世界中のエンジニアにとって愛される美しいものになることを応援しています!
コメント