Laravel Serviceクラスの役割
投稿日:2026/01/13
Laravelでアプリケーション開発を進めていると、Controllerに処理を詰め込みすぎてしまうという問題に直面しがちです。
その結果、Controllerが肥大化し、次のような課題が発生します。
- 処理内容が把握しづらい
- 再利用ができない
- テストが書きにくい
本記事では、その解決策としてよく使われるServiceクラスについて、
- なぜServiceクラスが必要なのか
- Serviceクラスの具体的な役割
- 基本的な使い方・考え方
を整理します。
Serviceクラスとは?
Serviceクラスとは、アプリケーションの業務ロジックをまとめるためのクラスです。
ここでいう「業務ロジック」とは、以下のような「アプリケーションとして何をするか」を表す処理を指します。
- データをどのようなルールで作成・更新するか
- 複数の処理をどの順番で実行するか
- 特定の条件下で何を行うか
LaravelにはServiceクラスに関する明確な公式ルールはありませんが、
Controllerの肥大化を防ぐための設計パターンとして、よく使用されています。
なぜServiceクラスが必要なのか
Controllerにすべて書いた場合
以下は、Controllerに処理をすべて記述した例です。
public function store(Request $request)
{
$validated = $request->validate([
'name' => 'required',
'value' => 'required',
]);
$sample = Sample::create([
'name' => $validated['name'],
'value' => $validated['value'],
'published_at' => now(),
]);
Mail::to(auth()->user())->send(new SampleCreatedMail($sample));
return redirect()->route('samples.index');
}
このControllerは、次の役割をすべて同時に担っています。
- リクエスト内容のバリデーション
- データベースへの保存処理
- 公開日時の決定
- メール送信
- 次に表示する画面の決定
1つのメソッドが複数の責務を持っており、変更に弱い状態です。
例えば、
- 同じ作成処理を別のControllerやCommandでも使いたい
- メール送信を条件付きにしたい
- テストでDBやMailを切り離したい
といった要望が出ると、修正範囲が広がりがちです。
Serviceクラスを使うとどうなるか
Serviceクラスに業務ロジックを移動する
データ作成やメール送信などの業務ロジックをServiceクラスにまとめます。
class SampleService
{
public function create(array $data): Sample
{
$sample = Sample::create([
'name' => $data['name'],
'value' => $data['value'],
'published_at' => now(),
]);
Mail::to(auth()->user())->send(new SampleCreatedMail($sample));
return $sample;
}
}
このServiceクラスは、
- Sampleを作成する
- 作成後にメールを送信する
という「作成処理の流れ」を表しています。
Controllerは「指示役」に専念する
Controllerでは、HTTPに関わる処理だけを担当します。
public function store(Request $request, SampleService $sampleService)
{
$validated = $request->validate([
'name' => 'required',
'value' => 'required',
]);
$sampleService->create($validated);
return redirect()->route('samples.index');
}
Controllerの役割は明確になります。
- 入力を受け取る
- Serviceに処理を依頼する
- どの画面に遷移するかを決める
「何をするか」ではなく、「誰に処理を任せるか」だけを書くのがポイントです。
Serviceクラスの役割まとめ
Serviceクラスの役割は、次のように整理できます。
| 役割 | 説明 |
|---|---|
| 業務ロジックの集約 | アプリケーション固有の処理を1か所にまとめる |
| Controllerの簡素化 | ControllerをHTTP制御に専念させる |
| 再利用性の向上 | 複数のController・Command・Jobから利用できる |
| テストしやすさ | HTTPに依存しないため単体テストを書きやすい |
Serviceに書くもの・書かないもの
Serviceに書くもの
- データの作成・更新ルール
- 複数Modelをまたぐ処理
- メール送信・通知処理
- データ加工処理
Serviceに書かないもの
- リクエストのバリデーション
- HTTPレスポンスの生成
- viewの指定
- redirectの制御
「HTTPに依存しない処理かどうか」 を判断基準にすると迷いにくくなります。
Serviceクラスの置き場所
よく使われるディレクトリ構成は次のとおりです。
app/
└── Services/
└── PostService.php
これはLaravelの公式規約ではありませんが、
チーム開発や保守を考えると、この構成が最も一般的です。
まとめ
- Serviceクラスは「業務ロジックの置き場所」
- Controllerは指示役、Serviceは実行役
- 責務を分離することで、可読性と保守性が向上する