49
37

More than 1 year has passed since last update.

LaravelでService層、Repository層を取り入れる方法とその必要性を簡潔に語る

Last updated at Posted at 2021-12-16

はじめに

Laravelでアプリケーションを実装するにあたり、Controllerがゴチャつくケースがよくあると思います。
例えばDBからデータを取得しフロントに表示するという単純な作業にしても、データを整形したりと色々コードを書いていく必要があります。
そうしているうちに一つのメソッドだけで数十行、数百行にもなってしまうこのようなControllerをFat Controllerと呼んだりします。
こうなってしまうとコードの可読性も悪いですし、拡張性が低いです。
この問題を解決するには役割分担をすることが最適解かと思われます。
今回はその方法について記述していきたいと思います。

やりたいこと

今回はフロントからリクエストしたidを使いhogeモデルからレコードを取得しjsonでフロントに返却するケースを想定。

フロントからリクエスト→Controller→Service→Repository→Model
という流れでこのユースケースを実現させる方法を記述します。

それぞれの役割

  • Controller
    フロントと、ビジネスロジックで取得したデータの橋渡しの役割を担います。
    今回はリクエストされたidを渡し、取得したデータをフロントに返す役割として使用します。

  • Service
    データの永続化に関わらないビジネスロジックをここに書きます。
    具体的にはモデルのユースケースを書いていきます。(crud)
    また今回の例でいうと、json整形のような取得したデータを加工しControllerに値を返す処理をここで実装ます。

  • Repository
    データの永続化に関わるビジネスロジック(データの保存などの操作)はここに書きます。
    今回はリクエストされたidを使いデータを取ってくるロジックをここで実装します。

appディレクトリ配下の構成

下記の構成で作っていきたいと思います。

app
├ Console
├ Exceptions
├ Http
│ ├ Controllers
│ │ └ HogeController.php →追加
│ ├ Middleware  
│ └ Requests
├ Models→追加
│ ├ Hoge.php→追加
├ Providers
│ ├ AppServiceProvider.php
├ Repositories →追加
│ ├ HogeRepository.php
│ └ HogeRepositoryInterface.php
└ Services →追加
  ├ HogeService.php →追加

準備

Hogeテーブルの準備

$ php artisan make:migration create_hoges_table
$ php artisan migrate

必要なディレクトリ及びファイルを追加

前項で「→追加」と書いている部分については自分で作成します。
ControllerとModelは以下コマンドで作成。

$ php artisan make:controller HogeController
$ php artisan make:model Hoge

AppServiceProviderに登録

サービスとリポジトリを使えるようにします。(正確にはDIしたいときのみ登録が必要)
registerメソッド内に2行追記。

AppServiceProvider.php

public function register()
    {
        $this->app->bind('App\Services\HogeService');
        $this->app->bind('App\Repositories\HogeRepositoryInterface', 'App\Repositories\HogeRepository');
    }

実装

Repository

まずはインターフェイスを作成。

HogeepositoryInterface.php
<?php

namespace App\Repositories;

interface HogeRepositoryInterface
{
    public function find($id);
}

行き→Service渡からってきたidを使いデータを取得する。
帰り→Modelから取得したデータをServiceに返す。

HogeRepository.php
<?php

namespace App\Repositories;

use App\Models\Hoge;

class HogeRepository implements HogeRepositoryInterface
{
    public function find($id)
    {
        return Hoge::find($id);
    }

Service

行き→Controllerから渡ってきたidをRepositoryに渡す。
帰り→Repositoryから返ってきたデータをjosn整形しControllerに返す。

HogeService.php
<?php

namespace App\Services;

use App\Repositories\HogeRepositoryInterface as HogeRepository;

class HogeService
{
    public function __construct(HogeRepository $hogeRepo)
    {
        $this->hogeRepositry = $hogeRepo;
    }

    public function find($id)
    {
        $hoge = $this->hogeRepositry->find($id);
        $respons = json_encode($hoge);
        return $respons;
    }

Controller

行き->フロントからリクエストされたidをServiceに渡す。
帰り->Serviceから返ってきた整形されたデータをフロントに返す。

HomeController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Services\HogeService;

class HogeController extends Controller
{
    public function __construct(HogeService $hogeService)
    {
        $this->hogeService = $hogeService;
    }

    public function find(Request $request)
    {
        return $this->hogeService->find($request->id)
    }
}

最後に

上記の実装で、フロントからリクエストした値を使いDBからレコードを取得する一連の流れを、役割分担しつつ実装できます。

49
37
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
49
37