Tech Starlog

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は実行役
  • 責務を分離することで、可読性と保守性が向上する