HOME / BLOG
BLOG

LaravelでAPIレスポンスを整える方法【Resource・Validation・Eloquent】

デフォルト画像

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でもこの形にしておくと、後から一覧、検索、外部連携を追加しやすくなります。