はじめに
Day13 では、
✅ ミドルウェアで「入口」を整える
✅ 認証・ログ・共通処理を集約する
ところまで進みました。
今日はその次の段階です。
❓ じゃあコントローラには何を書くべきなのか?
ここを間違えると、
Fat Controller(コントローラに記載が過多となる)問題 に突入します。
今日のゴール
・コントローラの「正しい役割」を説明できる
・Fat Controller がなぜダメか理解できる
・Service クラスを使って責務を分離できる
・「読める・保守できる API コード」を書ける
まず見てほしい「ダメなコントローラ」
public function store(Request $request)
{
// バリデーション
if (!$request->title) {
return response()->json(...);
}
// DB保存
$post = new Post();
$post->title = $request->title;
$post->save();
// 通知送信
Mail::to(...)->send(...);
// レスポンス
return response()->json(...);
}
一見動きますが、問題点は…
・処理が多すぎる
・テストしづらい
・仕様変更に弱い
・再利用できない
これが Fat Controller です。
適切な考え方:コントローラは「交通整理」
コントローラの役割はこれだけ。
「リクエストを受け取り、適切な処理に流し、レスポンスを返す」
つまり、
・ロジックは書かない
・判断は最小限
・処理は他に委譲
責務分離の基本構成
Request
↓
Controller(薄い)
↓
Service(ビジネスロジック)
↓
Model(DB操作)
実践:Service クラスを作る
① Service クラス作成
app/Services/PostService.php
<?php
namespace App\Services;
use App\Models\Post;
class PostService
{
public function create(array $data)
{
return Post::create([
'title' => $data['title'],
]);
}
}
② Controller から Service を呼ぶ
use App\Services\PostService;
class PostController extends Controller
{
public function store(Request $request, PostService $postService)
{
$post = $postService->create($request->only('title'));
return response()->json([
'status' => 'success',
'data' => $post
], 201);
}
}
何が良くなったのか?
| Before | After |
|---|---|
| ロジックが詰まっている | 処理が1行 |
| 読みにくい | 一目で分かる |
| テスト困難 | Service単体テスト可能 |
| 再利用不可 | 他APIから再利用可能 |
よくある疑問:どこまで分けるべき?
✔ 分けるべきもの
・ビジネスルール
・複数モデルをまたぐ処理
・将来変更されそうな処理
❌ 分けなくていいもの
・単純な1行取得
・その場限りの処理
「迷ったら分ける」くらいでOK です。
リクエストのバリデーションはどこに書く?
バリデーションは FormRequest に切り出します。
php artisan make:request StorePostRequest
public function rules()
{
return [
'title' => 'required|string|max:255'
];
}
Controller はさらに薄くなります。
public function store(StorePostRequest $request, PostService $postService)
{
$post = $postService->create($request->validated());
return response()->json([
'status' => 'success',
'data' => $post
], 201);
}
これが「綺麗な API コントローラ」
・ロジックが無い
・処理が流れるだけ
・役割が明確
・読んで安心できる
今日のまとめ
・コントローラは「交通整理役」
・Fat Controller は避ける
・ロジックは Service クラスへ
・バリデーションは FormRequest へ
・責務分離で保守性・可読性が爆上がり
次回 Day15
次はいよいよ 認証の核心 に入ります。
Day15 — JWTとは?仕組みを図解しながらLaravelで発行してみる
ここから
「本物の Web API」
になっていきます。