第23回: HTTPステータスコードの使い方 — 「全部200」は嘘のAPIになる

章: 第3章: RESTful API設計

バリデーションエラーも、サーバーエラーも、全部200で返していませんか?

エラーがあっても { "success": false } を200で返すAPIがあります。クライアントはHTTPステータスだけでは「成功か失敗か」が分からず、常にJSONのパースが必要になります。

適切なHTTPステータスコードを返すことで、クライアントはHTTPレイヤーでエラーを検知でき、ハンドリングが明確になります。

よく使うステータスコードの整理


# よく使うステータスコードの整理
# 200 OK               成功
# 201 Created          リソース作成成功
# 204 No Content       削除成功(本文なし)
# 400 Bad Request      リクエスト内容の不備
# 401 Unauthorized     認証が必要
# 403 Forbidden        認可されていない操作
# 404 Not Found        リソースが存在しない
# 422 Unprocessable    バリデーションエラー
# 500 Internal Error   サーバー側の予期せぬエラー

ステータスコードの使い分け早見表

状況 コード 意味
一覧・詳細取得成功 200 OK
新規作成成功 201 Created(Locationヘッダも推奨)
削除成功 204 No Content(ボディなし)
パラメータ形式エラー 400 Bad Request
未ログイン 401 Unauthorized
権限なし 403 Forbidden
リソースが見つからない 404 Not Found
バリデーションエラー 422 Unprocessable Entity
サーバー内部エラー 500 Internal Server Error

チェックポイント: 401と403の違いを混同しがちです。「誰かわからない」が401、「誰かはわかるが権限がない」が403です。

Laravelでのステータスコード設定


<?php
class PostController extends Controller {
    public function store(StorePostRequest $request): JsonResponse {
        $post = Post::create($request->validated());
        // 作成成功は201
        return response()->json(['success' => true, 'data' => $post], 201);
    }

    public function destroy(int $id): JsonResponse {
        Post::findOrFail($id)->delete();
        // 削除成功は204(ボディなし)
        return response()->noContent();
    }
}

チェックポイント: findOrFail() はリソースが存在しないと自動で404をスローします。これを活用すると if (!$post) { return 404; } のような手動チェックが不要になります。

まとめ & 次のステップ

  • 成功・エラー・作成・削除でそれぞれ適切なステータスコードを返す
  • 401(未認証)と403(認可エラー)を混同しないようにする
  • Laravelの findOrFail() で404の自動スローを活用する

次回はリクエストバリデーション設計を学びます。APIの入口でデータ品質を保証し、バリデーションエラーを統一フォーマットで返す方法です。

Related Articles