APIレスポンスにおけるJSON
JSON APIレスポンスの構造化ベストプラクティスを解説します。エンベロープパターン、エラーフォーマット、ページネーション、ステータスコード、主要APIプロバイダーの慣例を紹介します。
詳細な説明
JSONはREST APIレスポンスの支配的なデータ形式です。JSON仕様は構文を定義しますが、APIレスポンスの構造化方法は規定していません。時間の経過とともに、開発者が一貫性があり、予測可能で、利用しやすいAPIを構築するのに役立つコミュニティ慣例と標準が確立されてきました。
一般的なレスポンス構造:
2つの主要なアプローチは、フラットレスポンスとエンベロープパターンです:
フラットレスポンス(シンプルなAPIに推奨):
{
"id": 1,
"name": "Alice",
"email": "alice@example.com"
}
HTTPステータスコードが成功または失敗を伝えます。ボディにはリソースデータのみが含まれます。
エンベロープレスポンス(実際によく使用):
{
"status": "success",
"data": { "id": 1, "name": "Alice" },
"meta": { "requestId": "abc-123" }
}
外側のラッパーがペイロードとともにメタデータを提供します。HTTPステータスコードだけでは不十分な場合や、クライアントがレスポンスヘッダーに簡単にアクセスできない場合に有用です。
エラーレスポンスの慣例:
良いエラーレスポンスには、機械可読なコード、人間が読めるメッセージ、そしてオプションで詳細なバリデーションエラーが含まれます:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request body is invalid",
"details": [
{ "field": "email", "message": "Must be a valid email address" }
]
}
}
RFC 9457(Problem Details for HTTP APIs)などの標準は、type、title、status、detail、instance フィールドを含むエラーレスポンスの正式な構造を提供します。
ページネーション:
大きなコレクションはページネーションすべきです。一般的なパターン:
{
"data": [...],
"pagination": {
"page": 2,
"perPage": 20,
"total": 150,
"totalPages": 8
}
}
カーソルベースのページネーションはページ番号の代わりに不透明なカーソル文字列を使用し、大規模なデータセットでより効率的で、リクエスト間でアイテムが挿入・削除された場合の問題を回避します。
開発者がよくやるミス:
すべてのレスポンスに200 OKを返し、実際のステータスコードをボディに入れることは、HTTPステータスコードの目的に反し、標準的なHTTPクライアントやミドルウェアを壊します。もうひとつのミスは一貫性のないレスポンス構造です。{"data": ...} を返す場合もあれば、リソースを直接返す場合もあると、クライアントはレスポンスの形状を推測しなければなりません。また、データベースモデルをプレゼンテーション層なしで直接シリアライズし、パスワードハッシュや内部IDなどの機密フィールドを含む過剰なデータを返すこともあります。
ベストプラクティス:
一貫性を保ちましょう。すべてのエンドポイントが同じレスポンス構造に従うべきです。適切なHTTPステータスコード(200、201、204、400、401、404、500)を使用してください。常に Content-Type: application/json を返してください。デバッグ用にレスポンスにリクエストIDを含めましょう。破壊的変更を避けるためにAPIをバージョニングしてください。APIが複雑な場合はHATEOASリンクやJSON:APIのような標準化されたフォーマットを使用してください。
ユースケース
SaaSプラットフォームのREST APIレスポンスフォーマットを設計し、すべてのエンドポイントで一貫したエラーハンドリング、ページネーションメタデータ、レート制限情報を含める。