対象バージョン: Laravel 13.x / PHP 8.3+(2026年時点のシリーズ基準)
一次ソース: Routing / Controllers / Responses / Eloquent Resources / Validation
こんにちは。この記事では、Laravel 13.x で RESTful API を作成する基本手順を、現行の公式ドキュメントに沿って整理します。install:api による API ルーティングの有効化から、apiResource による CRUD、バリデーションと JSON レスポンス、Eloquent Resource の最小例までを通します。Passport・GraphQL・Sanctum の深掘りは扱いません。まずは「動く JSON API を自分で組める」状態を目指します。
この記事で分かること
- Laravel 13.x で API ルート(
routes/api.php)を有効にする手順 Route::apiResourceとmake:controller --apiによる CRUD- バリデーション失敗時の 422 JSON
response()->jsonと Eloquent Resource の最小利用- API 認証の概要(
auth:sanctumの高レベル言及)
対象バージョン
本記事の前提は Laravel 13.x / PHP 8.3+ です。Laravel 13 は 2026年3月17日リリースの現行メジャーであり、サポート表上 PHP 8.3〜8.5 を対象とします(Release Notes)。フレームワーク本体も php: ^8.3 を要求します。
古い記事にあった文字列コントローラルート(例: PostController@index)は、現行 Laravel の既定では自動名前空間解決されず、学習用の主例として不適切です。以降は配列構文または apiResource のみを使います。
APIルーティングの準備
fresh な 13.x には routes/api.php がありません
laravel/laravel 13.x の fresh スケルトンの routes/ には、既定で web.php と console.php のみがあります。routes/api.php は最初から存在しません。また bootstrap/app.php も、既定では withRouting に api: 引数がありません。
php artisan install:api で有効化する
ステートレスな API を提供する場合は、次のコマンドで API ルーティングを有効化します(Routing — API Routes)。
php artisan install:api
このコマンドは Laravel Sanctum をインストールし、routes/api.php を作成します。以降のルート例は、この手順を済ませた前提です。
/api 接頭辞と api ミドルウェアグループ
routes/api.php に書いたルートには、自動で /api URI 接頭辞 が付きます。たとえば Route::get('/posts', ...) の実 URL は /api/posts です。あわせて、これらのルートは ステートレス で、api ミドルウェアグループ に割り当てられます。
install:api が生成する例には auth:sanctum が付いていることがあります。公開してよいルートでは auth:sanctum を省略して構いません。保護したいルートにだけ付けます。
APIルーティング
CRUD の REST エンドポイントは、個別に5本書くより Route::apiResource を使うのが公式の推奨です。create / edit(HTML 用)ルートは含まれません。
<?php
use App\Http\Controllers\Api\PostController;
use Illuminate\Support\Facades\Route;
Route::apiResource('posts', PostController::class);
登録されるアクションと HTTP 動詞の対応は次のとおりです(実 URL はすべて /api 接頭辞付き)。
| メソッド | URI | アクション |
|---|---|---|
| GET | /api/posts |
index |
| POST | /api/posts |
store |
| GET | /api/posts/{post} |
show |
| PUT/PATCH | /api/posts/{post} |
update |
| DELETE | /api/posts/{post} |
destroy |
個別に定義する場合は、配列構文のみを使います。
Route::get('/posts', [PostController::class, 'index']);
Route::post('/posts', [PostController::class, 'store']);
Route::get('/posts/{post}', [PostController::class, 'show']);
Route::put('/posts/{post}', [PostController::class, 'update']);
Route::delete('/posts/{post}', [PostController::class, 'destroy']);
使わない構文:
'PostController@index'のような文字列コントローラルートは、現行の主例にしません。
APIコントローラ
API 用のリソースコントローラは、--api オプション付きで生成します。
php artisan make:controller Api/PostController --api
create / edit を含まず、index / store / show / update / destroy が用意されます。サブディレクトリ(例: Api/)も問題ありません。
show / update / destroy では、暗黙のルートモデルバインディングを使うと簡潔です。ルートパラメータ {post} と型ヒント Post $post が一致すればモデルが注入され、見つからない場合は 404 になります。
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function show(Post $post)
{
return $post;
}
}
(モデルを直接返すと、hidden 属性を尊重しつつ自動で JSON になります。実務では後述の Resource か response()->json に寄せると見通しが良くなります。)
バリデーションとエラーJSON
入力検証は、Web と同様に $request->validate([...]) または Form Request の型ヒントで行えます。
public function store(Request $request)
{
$validated = $request->validate([
'title' => ['required', 'string', 'max:255'],
'body' => ['required', 'string'],
]);
$post = Post::create($validated);
return response()->json($post, 201);
}
XHR / JSON を期待するリクエストでバリデーションに失敗すると、リダイレクトではなく 422 Unprocessable Entity と、message / errors 形式の JSON が返ります(Validation)。API クライアント側はこのステータスを前提にエラー表示を組み立てるとよいです。
レスポンスのフォーマット
response()->json
response()->json($data, $status) で Content-Type: application/json のレスポンスを返せます。第2引数で HTTP ステータスを指定します(既定は 200。作成時は 201 など)。
return response()->json(['message' => 'Post created successfully'], 201);
よく使うステータスの目安です。
| コード | 用途の例 |
|---|---|
| 200 | 取得・更新の成功 |
| 201 | 作成の成功 |
| 404 | リソース未検出(ルートモデルバインディング含む) |
| 422 | バリデーション失敗 |
Eloquent API Resource(最小)
変換層として Eloquent API Resource を使うと、公開する属性を明示できます。
php artisan make:resource PostResource
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class PostResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'title' => $this->title,
'body' => $this->body,
'created_at' => $this->created_at,
];
}
}
コントローラからは次のように返します。
use App\Http\Resources\PostResource;
return new PostResource($post);
// 一覧
return PostResource::collection(Post::all());
入門では単一 Resource と ::collection までで十分です。
API認証(概要)
install:api により Laravel Sanctum が入ります。保護したいルートには auth:sanctum ミドルウェアを付けます。
Route::middleware('auth:sanctum')->group(function () {
Route::apiResource('posts', PostController::class);
});
公開ルートではこの middleware を付けなくて構いません。トークン発行の詳細、SPA Cookie 認証、Passport、カスタムガードなどは本記事の範囲外です。API トークン認証が必要になったら、公式の Sanctum を参照してください。
最小CRUDの流れ
ここまでの手順を、動作イメージとして並べます。
php artisan install:api—routes/api.phpと Sanctum を用意- モデル/マイグレーション — 例:
Post(Eloquent 前提は既存知識で可) php artisan make:controller Api/PostController --api- (任意)
php artisan make:resource PostResource routes/api.phpにRoute::apiResource('posts', PostController::class);- 各アクションで
validate→ 永続化 →PostResourceまたはresponse()->json(..., 201)
コントローラの最小実装例です。
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Resources\PostResource;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index()
{
return PostResource::collection(Post::all());
}
public function store(Request $request)
{
$validated = $request->validate([
'title' => ['required', 'string', 'max:255'],
'body' => ['required', 'string'],
]);
$post = Post::create($validated);
return response()->json($post, 201);
}
public function show(Post $post)
{
return new PostResource($post);
}
public function update(Request $request, Post $post)
{
$validated = $request->validate([
'title' => ['required', 'string', 'max:255'],
'body' => ['required', 'string'],
]);
$post->update($validated);
return new PostResource($post);
}
public function destroy(Post $post)
{
$post->delete();
return response()->json(['message' => 'Post deleted successfully']);
}
}
補足: 作成成功は
201、取得・更新・削除成功は既定の200を使う例です。ステータスはプロジェクトの方針に合わせて調整してください。
動作確認の例(ローカル):
# 一覧
curl -s http://127.0.0.1:8000/api/posts
# 作成
curl -s -X POST http://127.0.0.1:8000/api/posts \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"title":"Hello","body":"API"}'
Accept: application/json を付けると、バリデーション失敗時に 422 JSON を受け取りやすくなります。
最後に
Laravel 13.x で RESTful API を作る流れは、次のようにまとめられます。
php artisan install:apiでroutes/api.php(/api接頭辞)を有効化make:controller ... --apiとRoute::apiResourceで CRUD を登録validateと 422 JSON、response()->json/ Eloquent Resource で応答を整える- 必要なルートだけ
auth:sanctumで保護
タイトルどおり「RESTful API を作成する」入口として、まずはこの最小 CRUD を動かしてみてください。認証の詳細や高度な API 設計は、公式ドキュメントへ進むとよいです。