サイトのAPI図鑑B版
掲載情報が正確でない可能性があります。
API基礎・入門

APIエラーハンドリングの完全ガイド【設計・実装・クライアント対応】

APIのエラーハンドリングについて、サーバー側の設計とクライアント側の実装の両面から解説。適切なHTTPステータスコード・エラーレスポンス設計・リトライ戦略を紹介します。

#エラーハンドリング#HTTP#API設計#例外処理

なぜエラーハンドリングが重要か

APIのエラーハンドリングは、利用者の開発体験と本番環境の信頼性に直結します。適切なエラーハンドリングにより、開発者はエラーの原因を素早く特定でき、エンドユーザーには適切なメッセージを表示できます。逆に不適切なエラーハンドリングは、デバッグに無駄な時間を費やす原因となり、場合によってはセキュリティリスクにもなります。

サーバー側:エラーレスポンスの設計

一貫したエラーレスポンス構造

エラーレスポンスは一貫した構造を持つことが重要です。RFC 9457(Problem Details for HTTP APIs)に準拠した形式が推奨されます。

{
  "type": "https://api.example.com/errors/validation-error",
  "title": "バリデーションエラー",
  "status": 422,
  "detail": "入力データが不正です",
  "instance": "/v1/users",
  "errors": [
    {
      "field": "email",
      "code": "INVALID_EMAIL",
      "message": "メールアドレスの形式が正しくありません"
    }
  ]
}

エラーレスポンスに含めるべき情報:

  • HTTPステータスコード:エラーの種類を示す
  • エラーコード:機械的に処理できるエラー識別子
  • エラーメッセージ:人間が読めるエラー説明
  • 対象フィールド:バリデーションエラーの場合はどのフィールドで問題が起きたか
  • リクエストID:サポート問い合わせ時に追跡できる一意のID

HTTPステータスコードの適切な使用

4xx系(クライアントエラー):リクエストに問題がある。修正すれば解決できる。

5xx系(サーバーエラー):サーバー側の問題。クライアントはリトライを検討できる。

特に注意すべきは「成功でも失敗でも200を返す」設計を避けることです。{status: "error"}をボディに含めつつ200を返す設計はHTTPの意味論と相反し、クライアント実装を複雑にします。

バリデーションエラーの扱い

フォーム送信やAPIリクエストでよく発生するバリデーションエラーは、どのフィールドにどんな問題があるかを明示することが重要です。複数フィールドにエラーがある場合は、最初の1件だけでなく全てのエラーをまとめて返すことで、利用者がまとめて修正できます。

非同期処理のエラーハンドリング

Webhookや非同期ジョブでのエラーはリクエスト時点では検知できません。以下の戦略が有効です。

  • ジョブのステータスを確認できるエンドポイントを用意する(GET /jobs/123)
  • 処理完了・失敗をWebhookで通知する
  • 失敗したジョブのエラー詳細を保存しておく

クライアント側:エラーの適切な処理

エラーの種類に応じた処理分岐

クライアントはHTTPステータスコードとエラーコードを使って、エラーの種類に応じた適切な処理を行います。

  • 401 Unauthorized:アクセストークンを更新して再試行、または再ログインへ誘導
  • 403 Forbidden:権限不足メッセージを表示(再試行しても無意味)
  • 404 Not Found:リソースが存在しないことをユーザーに通知
  • 422 Unprocessable Entity:バリデーションエラーをフォームのフィールドに対応させて表示
  • 429 Too Many Requests:Retry-Afterヘッダーの時間待機してリトライ
  • 500 Internal Server Error:「しばらく時間をおいてから再試行してください」を表示

リトライ戦略

一時的なエラー(429・503・504)にはエクスポネンシャルバックオフでリトライします。リトライ上限(最大3〜5回)を設定し、リトライ限界に達したらユーザーに通知します。冪等性のないPOSTリクエストのリトライは二重登録のリスクがあるため注意が必要です。

エラーログの設計

クライアント側でもエラーをログに記録することが重要です。特にSentryのようなエラートラッキングサービスを使えば、本番環境で発生したエラーを集約して分析できます。リクエストID・エンドポイント・エラーコード・タイムスタンプを必ずログに含めてください。

グローバルエラーハンドラーの実装

APIクライアントにグローバルエラーハンドラーを実装することで、認証エラー・ネットワークエラーなどの共通処理を一箇所にまとめられます。axiosのインターセプター、fetchのラッパー関数、またはSDKのエラーハンドラーを活用します。

まとめ

APIのエラーハンドリングはサーバー・クライアントの両面から設計する必要があります。サーバー側では一貫したエラーレスポンス構造と適切なHTTPステータスコードを、クライアント側ではエラーの種類に応じた分岐とリトライ戦略を実装してください。エラーハンドリングへの投資は、長期的な開発効率と本番環境の信頼性向上につながります。

よくある質問

Q.400と422の使い分けはどうすればよいですか?

400 Bad Requestはリクエストの構文が不正な場合(JSONのパースエラー、必須パラメーターの欠落等)に使います。422 Unprocessable Entityはリクエストの構文は正しいが内容が処理できない場合(バリデーションエラー、ビジネスロジック違反等)に使います。

Q.エラーの詳細を返しすぎるとセキュリティリスクになりますか?

はい。スタックトレース・データベース名・内部ファイルパスなどのシステム内部情報をエラーレスポンスに含めると、攻撃者に有用な情報を与えてしまいます。本番環境では人間が読めるメッセージとエラーコードのみを返し、詳細情報はサーバーログに記録してください。

Q.クライアント側でどのエラーをリトライすべきですか?

リトライすべきエラー:429 Too Many Requests(レート制限)、503 Service Unavailable(一時的なサービス停止)、504 Gateway Timeout。リトライすべきでないエラー:400 Bad Request(リクエスト内容が不正、同じリクエストを送っても失敗し続ける)、401 Unauthorized(認証失敗)、403 Forbidden(権限なし)、404 Not Found。

関連記事