1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Day11 — HTTPステータスコードを正しく返す Laravel API 実装

1
Last updated at Posted at 2025-12-10

はじめに

Day10 では、React から Laravel API に
✅ GET
✅ POST
で通信できるようになりました。

さて、ここで質問です。

あなたの API、こんな実装になっていませんか?

return response()->json($data);

✅ すべて 200 OK
✅ エラーでも 200 OK
✅ 失敗しても 200 OK

これ、実務では当然やってはならず、かなり危険な設計です。

今日は

✅ HTTP ステータスコードの本当の役割
✅ Laravel で正しく返す方法
✅ フロント側で「成功・失敗」を正しく分岐させる書き方

を徹底的に整理します。

今日のゴール

200 / 201 / 400 / 401 / 404 / 500 の意味が分かる

・成功と失敗で HTTP ステータスを分けて返せる

・フロント 側でレスポンス分岐が正しく見分けられる

・「全部 200 API」を書かずに済む

そもそも HTTP ステータスコードの役割とは?

ステータスコードは一言で言うと、

「このリクエストが “どういう結果だったか” を一瞬で伝える合図」

です。

つまり、

・成功なのか?

・クライアントのミスなのか?

・サーバのミスなのか?

数字だけで表現するルール です。

最低限これだけは覚えたいステータスコード

ステータス 意味 いつ使う?
200 OK 取得・更新成功
201 Created 新規作成成功
400 Bad Request バリデーションエラー
401 Unauthorized 未ログイン
403 Forbidden 権限なし
404 Not Found データが存在しない
500 Server Error サーバ内部エラー

✅ まずは この7つだけで実務は回ります。

ダメな API の例(全部 200)

return response()->json([
  'message' => 'エラーです'
]);

これだとフロント側はこうなります。

.then(res => {
  // 成功なの?失敗なの?
  // 中身を見ないと分からない…
});

✅ 機械が正しく分岐できない
✅ エラー処理が破綻する

正しい API の返し方(成功編)

一覧取得(200 OK)

return response()->json([
  'status' => 'success',
  'data' => $posts
], 200);

新規作成(201 Created)

return response()->json([
  'status' => 'success',
  'message' => '投稿を作成しました',
  'data' => $post
], 201);

「作成成功」は 201 を返すのが正しい作法

正しい API の返し方(失敗編)

バリデーションエラー(400 Bad Request)

if (empty($request->title)) {
  return response()->json([
    'status' => 'error',
    'message' => 'タイトルは必須です'
  ], 400);
}

未ログイン(401 Unauthorized)

return response()->json([
  'status' => 'error',
  'message' => 'ログインが必要です'
], 401);

データが存在しない(404 Not Found)

$post = Post::find($id);

if (!$post) {
  return response()->json([
    'status' => 'error',
    'message' => '投稿が見つかりません'
  ], 404);
}

サーバエラー(500 Internal Server Error)

try {
  // 何かの処理
} catch (\Exception $e) {
  return response()->json([
    'status' => 'error',
    'message' => 'サーバエラーが発生しました'
  ], 500);
}

フロント側(React)での正しい分岐

fetch('http://localhost:8000/api/posts')
  .then(async (res) => {
    if (!res.ok) {
      const error = await res.json();
      throw new Error(error.message);
    }
    return res.json();
  })
  .then((data) => {
    console.log('成功', data);
  })
  .catch((err) => {
    alert(err.message);
  });

✅ ステータスコードで
✅ 自動的に成功・失敗が分岐できる

初心者が必ずやるステータス事故

エラーなのに 200 を返す

return response()->json(['error' => 'NG'], 200);

→ React 側が「成功」と判断してしまう

作成成功なのに 200 を返す

return response()->json($post, 200);

→ ✅ 正解は 201 Created

ステータスは正しいが JSON がバラバラ

{ "result": "ok" }
{ "success": true }
{ "status": "success" }

✅ レスポンス形式は 必ず統一する

実務でよく使われる成功・失敗フォーマット例

// 成功
{
  "status": "success",
  "data": {}
}

// 失敗
{
  "status": "error",
  "message": "エラーメッセージ"
}

✅ この形式を 全APIで統一するだけで保守性が上がり します。

今日のまとめ

・HTTP ステータスは「結果の意味」を伝える重要な情報

・成功 → 200 / 201

・失敗 → 400 / 401 / 403 / 404 / 500

・Laravel では response()->json(データ, ステータス) で制御する

・フロント側では res.ok で分岐する

次回 Day12 は…

「JSONレスポンスのベストプラクティス(成功・失敗・一覧・詳細の設計)」

レスポンスが
❌ バラバラ
→ ✅ 美しく統一された API

に進化します。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?