LaravelでAPIを作るとき、最初はControllerから配列を返すだけでも動きます。ただ、開発が進むと、入力チェック、レスポンス形式、日付の表記、不要なカラムの除外を毎回Controllerに書くことになり、保守しにくくなります。
この記事では、Form RequestとEloquent Resourceを使って、LaravelのAPIレスポンスを整理する基本構成をまとめます。
APIで分けたい責務
- 入力チェック:Form Request
- 保存処理:ControllerまたはService
- データ取得:Eloquent Model
- JSON整形:Eloquent Resource
Form Requestで入力チェックを分ける
Controllerにバリデーションルールを直接書くと、処理が増えるほど読みづらくなります。Form Requestへ分けると、入力チェックの責務が明確になります。
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreArticleRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'title' => ['required', 'string', 'max:120'],
'slug' => ['required', 'alpha_dash', 'max:140', 'unique:articles,slug'],
'body' => ['required', 'string'],
'published_at' => ['nullable', 'date'],
];
}
}
Resourceでレスポンス形式を固定する
Eloquent Resourceを使うと、DBのカラムをそのまま返すのではなく、APIとして返したい形へ変換できます。公開したくないカラムを隠したり、日付表記を揃えたりする場所として使えます。
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class ArticleResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'title' => $this->title,
'slug' => $this->slug,
'body' => $this->body,
'published_at' => optional($this->published_at)->toISOString(),
'created_at' => $this->created_at->toISOString(),
'updated_at' => $this->updated_at->toISOString(),
];
}
}
Controllerを薄くする
入力チェックとJSON整形を外へ出すと、Controllerは「受け取る、保存する、返す」に集中できます。
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Requests\StoreArticleRequest;
use App\Http\Resources\ArticleResource;
use App\Models\Article;
class ArticleController extends Controller
{
public function store(StoreArticleRequest $request): ArticleResource
{
$article = Article::create($request->validated());
return new ArticleResource($article);
}
public function show(Article $article): ArticleResource
{
return new ArticleResource($article);
}
}
API設計で気をつけること
- DBカラムをそのまま全部返さない
- 日付形式をAPI内で統一する
- バリデーションエラーはLaravel標準の422レスポンスに寄せる
- 一覧APIではページネーションとResource Collectionを検討する
- フロント側が使う項目だけを返す
NINES ANALYZEのようなデータ系サイトで使いやすい場面
Bリーグのチーム成績、選手成績、ランキングのようなデータをAPIで返す場合、Resourceを挟むとフロント側が扱いやすくなります。DBの都合ではなく、画面や分析用途に合わせたJSONへ変換できるからです。
あわせて読みたい
参考資料
まとめ
LaravelでAPIを作るなら、Controllerに全部書くよりも、Form Requestで入力チェック、ResourceでJSON整形を分けた方が保守しやすくなります。小さなAPIでもこの形にしておくと、後から一覧、検索、外部連携を追加しやすくなります。