HTTPステータスコードの使い分け
HTTPステータスコードの使い分け
APIの設計において、適切なHTTPステータスコードの選択は、クライアント側の処理分岐を明確にし、デバッグ効率を大幅に向上させる重要な要素です。本記事では、実務で頻繁に使用されるステータスコードの特性と、実践的な使い分け方法を詳しく解説します。
HTTPステータスコードの基本分類
HTTPステータスコードは5つのカテゴリに分類されます:
- 1xx (Informational): 情報レスポンス
- 2xx (Success): 成功レスポンス
- 3xx (Redirection): リダイレクト
- 4xx (Client Error): クライアントエラー
- 5xx (Server Error): サーバーエラー
1xx 情報レスポンス
100 Continue - 継続中
使用場面: リクエストが継続中
2xx 成功レスポンス
200 OK - 汎用成功
使用場面: リクエストが正常に処理された
GET /api/users/123
HTTP/1.1 200 OK
{
"id": 123,
"name": "田中太郎",
"email": "tanaka@example.com"
}
適用ケース:
- データ取得の成功
- 更新処理の成功
- 削除処理の成功(レスポンスボディがある場合)
201 Created - リソース作成成功
使用場面: 新しいリソースが正常に作成された
POST /api/users
HTTP/1.1 201 Created
Location: /api/users/124
{
"id": 124,
"name": "佐藤花子",
"email": "sato@example.com"
}
重要ポイント:
-
Locationヘッダーで新しいリソースのURLを指定 - レスポンスボディに作成されたリソース情報を含める
204 No Content - 成功(レスポンスボディなし)
使用場面: 処理は成功したがレスポンスボディが不要
DELETE /api/users/123
HTTP/1.1 204 No Content
適用ケース:
- DELETE操作の成功
- PUT操作でレスポンスが不要な場合
- PATCH操作でレスポンスが不要な場合
3xx リダイレクト
301 Moved Permanently - 永続的リダイレクト
使用場面: リソースが永続的に移動した
GET /api/v1/users
HTTP/1.1 301 Moved Permanently
Location: /api/v2/users
302 Found - 一時的リダイレクト
使用場面: サーバーメンテナンスで使われる
GET /api/users/profile
HTTP/1.1 302 Found
Location: /login
304 Not Modified - キャッシュ有効
使用場面: キャッシュされたリソースが最新状態
GET /api/users/123
If-None-Match: "abc123"
HTTP/1.1 304 Not Modified
4xx クライアントエラー
400 Bad Request - 不正なリクエスト
使用場面: リクエストの構文や内容に問題がある
POST /api/users
{
"name": "",
"email": "invalid-email"
}
HTTP/1.1 400 Bad Request
{
"error": "Validation failed",
"details": [
{
"field": "name",
"message": "名前は必須です"
},
{
"field": "email",
"message": "有効なメールアドレスを入力してください"
}
]
}
適用ケース:
- バリデーションエラー
- JSONの構文エラー
- 必須パラメータの不足
401 Unauthorized - 認証が必要
使用場面: 認証情報が必要または無効
GET /api/users/profile
HTTP/1.1 401 Unauthorized
{
"error": "Authentication required",
"message": "有効なアクセストークンが必要です"
}
重要な違い:
- 401: 認証情報が不正または未提供
- 403: 認証済みだが権限不足
403 Forbidden - アクセス権限なし
使用場面: 認証済みだが操作権限がない
DELETE /api/users/999
HTTP/1.1 403 Forbidden
{
"error": "Insufficient permissions",
"message": "他のユーザーのアカウントは削除できません"
}
404 Not Found - リソースが存在しない
使用場面: 指定されたリソースが見つからない
GET /api/users/99999
HTTP/1.1 404 Not Found
{
"error": "User not found",
"message": "指定されたユーザーは存在しません"
}
409 Conflict - リソースの競合
使用場面: リソースの状態が競合している
POST /api/users
{
"email": "existing@example.com"
}
HTTP/1.1 409 Conflict
{
"error": "Email already exists",
"message": "このメールアドレスは既に使用されています"
}
適用ケース:
- 一意制約違反
- 楽観的ロックの競合
- ビジネスルールの競合
422 Unprocessable Entity - 処理不可能なエンティティ
使用場面: 構文は正しいが、意味的に処理できない
POST /api/orders
{
"productId": 123,
"quantity": -5
}
HTTP/1.1 422 Unprocessable Entity
{
"error": "Invalid business logic",
"message": "数量は正の数である必要があります"
}
400との使い分け:
- 400: 構文エラー、形式エラー
- 422: ビジネスロジックエラー
429 Too Many Requests - レート制限
使用場面: リクエスト頻度が制限を超えた
GET /api/users
HTTP/1.1 429 Too Many Requests
Retry-After: 60
{
"error": "Rate limit exceeded",
"message": "1分後に再試行してください"
}
5xx サーバーエラー
500 Internal Server Error - 内部サーバーエラー
使用場面: サーバー側の予期しないエラー
GET /api/users
HTTP/1.1 500 Internal Server Error
{
"error": "Internal server error",
"message": "一時的なエラーが発生しました。しばらく後に再試行してください"
}
注意点: 詳細なエラー情報は本番環境では返さない
502 Bad Gateway - 不正なゲートウェイ
使用場面: プロキシサーバーが上流サーバーから無効なレスポンスを受信
HTTP/1.1 502 Bad Gateway
{
"error": "Bad gateway",
"message": "サービスが一時的に利用できません"
}
503 Service Unavailable - サービス利用不可
使用場面: サーバーが一時的にリクエストを処理できない
HTTP/1.1 503 Service Unavailable
Retry-After: 120
{
"error": "Service unavailable",
"message": "メンテナンス中です。2分後に再試行してください"
}
実践的な使い分け指針
バリデーションエラーの分類
リクエスト形式が不正 → 400
ビジネスルール違反 → 422
一意制約違反 → 409
認証・認可エラーの分類
トークンなし/無効 → 401
権限不足 → 403
リソースが存在しない → 404
成功レスポンスの選択
データ取得 → 200
リソース作成 → 201
削除・更新(レスポンス不要) → 204
レスポンスボディの設計
エラーレスポンスは一貫した形式で返すことが重要です:
{
"error": "error_code",
"message": "ユーザー向けメッセージ",
"details": [
{
"field": "email",
"code": "INVALID_FORMAT",
"message": "有効なメールアドレスを入力してください"
}
],
"timestamp": "2024-09-16T10:30:00Z",
"path": "/api/users"
}
まとめ
適切なHTTPステータスコードの使用は、API設計の品質を大きく左右します。クライアント側の処理を簡潔にし、デバッグ効率を向上させるため、各ステータスコードの意味を正確に理解し、一貫性のある使い方を心がけましょう。
特に、400と422、401と403の使い分けは実務でよく迷うポイントなので、チーム内でガイドラインを策定することをお勧めします。
Discussion