APIエラーの「迷子」をなくそう!RFC 7807で実現する、優しく伝わるエラーハンドリングの世界
こんにちは!ネットワークとAPIの深淵を日々探求しているインフラエンジニアです。
皆さんは、Webサービスを使っていて「エラーが発生しました」という無機質なメッセージだけで、結局何が悪いのか分からずイライラした経験はありませんか?
実はこれ、APIを作る側にとっても大きな課題なんです。クライアント(アプリ側)がエラーの原因を正確に把握できないと、ユーザーに正しい解決策を提示できません。そんな「エラーの伝言ゲーム」を終わらせるための魔法のルールが、今回ご紹介する RFC 7807: Problem Details for HTTP APIs です。
一歩ずつ、郵便の仕組みに例えて紐解いていきましょう!
—
なぜ「エラーの詳細」を標準化する必要があるの?
想像してみてください。あなたが海外の友人に手紙を出したとき、住所が間違っていて「宛先不明」で戻ってきたとします。
- ダメなパターン: 郵便局から「何か問題があったので送れません」とだけ書かれたメモが届く。
- 理想のパターン: 郵便局から「『番地が記入されていません』という理由で返送しました。修正して再送してください」という丁寧な通知が届く。
APIも全く同じです。サーバー側でエラーが起きたとき、ただ「HTTP 400 Bad Request(リクエストが変だよ)」と返すだけでは、クライアントは「何が変なの?」と途方に暮れてしまいます。
そこで登場するのが、application/problem+json という「標準化された配送伝票」です。これを使うことで、エラーの種類や解決策を、世界共通のルールで相手に伝えられるようになるんです。
—
RFC 7807が定義する「伝票」の中身
RFC 7807では、エラーレスポンスに含めるべき項目を定めています。これらを使うことで、クライアントはプログラム的に「今は何をすべきか」を判断できるようになります。
代表的な項目を見てみましょう。
type: この問題が何であるかを示すURI(エラーの辞書のようなもの)。title: 人間が読んでパッと分かる短い説明。status: HTTPステータスコード(400や404など)。detail: なぜエラーになったのかという、具体的な解説。instance: この特定のエラーが発生した場所(リクエストのパスなど)。
—
実践!美しいエラーレスポンスを書いてみよう
では、実際にどのようなJSONになるのか、Python(Flask)を例に見てみましょう。例えば、「銀行口座の残高不足」で決済が失敗したというシチュエーションです。
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/transfer', methods=['POST'])
def transfer():
# 本来はここにロジックが入ります
# 今回は「残高不足」というエラーをシミュレートします
response_body = {
# エラーの種類を示すURI
"type": "https://api.example.com/probs/insufficient-funds",
# 画面に表示するタイトル
"title": "残高が足りません",
# HTTPステータスコード
"status": 403,
# なぜエラーなのかの詳細
"detail": "現在の残高は500円ですが、送金額は2000円です。",
# どのリクエストで起きたか
"instance": "/account/12345/transfer"
}
# application/problem+json として返却するのがポイント!
return jsonify(response_body), 403, {'Content-Type': 'application/problem+json'}
このように返してあげれば、クライアント側のエンジニアは「おっ、type がこれなら、ユーザーに残高チャージ画面へのリンクを表示してあげよう!」といった自動的な制御が可能になります。
—
インフラエンジニアからのアドバイス:運用で気をつけること
最後に、現場でこの仕組みを導入する際の「コツ」を2つお伝えします。
1. セキュリティに注意!: detail フィールドに、データベースの内部構造やパスワードのハッシュ値など、攻撃者にヒントを与える情報を載せてはいけません。「内部エラーが発生しました」という嘘はつかなくても良いですが、情報は「必要最小限」に留めましょう。
2. type URIを有効活用する: type に指定するURLには、実際にそのエラーの詳細を解説したドキュメントを置いておくとベストです。開発者が「これってどういう意味?」と悩んだときに、すぐに答えに辿り着ける親切なAPIになります。
まとめ
RFC 7807は、単なる「お作法」ではありません。クライアントとサーバー間の「対話」を円滑にするためのコミュニケーションツールです。
最初は少し手間がかかるように感じるかもしれませんが、一度この形式でAPIを設計しておくと、後のトラブルシューティングが劇的に楽になります。「あのAPI、エラーが分かりやすくて助かるよ!」と仲間に感謝される日も遠くありません。
ぜひ皆さんのプロジェクトでも、この「標準化された伝票」を取り入れてみてくださいね。それでは、また次回の深掘り解説でお会いしましょう!
コメント