メリット
- 各ファイルから呼び出すDB操作 (取得・追加・更新・削除)を共通化できる
- DB操作に関するロジックをControllerのビジネスロジックから切り離すことで、
メソッドがシンプルになり、処理の流れが読みやすくなる & 保守・拡張性が高まる - Repositoryのインターフェースで型指定をすることで、バグ防止にも繋がる
ざっくりとした流れ
- リポジトリディレクトリ&ファイルを作成
- ServiceProviderに登録し、
config/app.php
に設定を追記 - Controller改修
まず、参考までに移動前のControllerを置いておく
- ProjectController.php
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Project;
class ProjectController extends Controller
{
/**
* @var App\Models\Project
*/
private $project;
public function __construct(Project $project) {
$this->project = $project;
}
/**
* 一覧
*
* @return \Illuminate\Http\JsonResponse
*/
public function index()
{
$projects = $this->project->get()->orderBy('updated_at', 'desc');
return response()->json(['projects' => $projects], 200, [], JSON_PRETTY_PRINT);
}
/**
* 新規作成
*
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function store(Request $request)
{
$data = $request->all();
$project = $this->project->create($data);
$this->updateLabels($project, $data);
return response()->json(['project' => $project], 200, [], JSON_PRETTY_PRINT);
}
protected function updateLabels(Project $project, array $data)
{
// ...省略
}
これを切り分けるためにリポジトリ実装していく
1. リポジトリを入れるディレクトリを作成
mkdir app/Repositories
mkdir app/Repositories/Project
app/Repositoriesに全ファイル入れてもいいけど、
ファイルが増えてくるとみづらくなるため対象テーブルごとにディレクトリを分けてる
リポジトリファイル作成
- インターフェースを生成: app/Repositories/Project/ProjectRepositoryInterface.php
<?php
namespace App\Repositories\Project;
use App\Models\Project;
use Illuminate\Database\Eloquent\Collection;
interface ProjectRepositoryInterface
{
public function getAll(): Collection;
public function store(array $data): Project;
}
- ロジックファイルを生成: app/Repositories/Project/ProjectRepository.php
<?php
namespace App\Repositories\Project;
use App\Models\Project;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\DB;
class ProjectRepository implements ProjectRepositoryInterface
{
/**
* @var App\Models\Project
*/
private $project;
public function __construct(Project $project) {
$this->project = $project;
}
/**
* 案件を全件取得する
*
* @return Collection
*/
public function getAll(): Collection
{
return $this->project->get()->orderBy('updated_at', 'desc');
}
/**
* 案件を登録する
*
* @param array $data
* @return Project
*/
public function store(array $data): Project
{
// 案件登録
$project = $this->project->create($data);
// ラベル更新
$this->updateLabels($project, $data);
return $project;
}
protected function updateLabels(Project $project, array $data)
{
// ...省略
}
}
ServiceProviderに登録
わかりやすいように
Repository用のServiceProviderを新規作成する
php artisan make:provider RepositoryServiceProvider
register
関数に作成したRepositoryファイルを追加していく
- RepositoryServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class RepositoryServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
$this->app->bind(
\App\Repositories\Project\ProjectRepositoryInterface::class,
\App\Repositories\Project\ProjectRepository::class
);
}
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
//
}
}
作成したRepositoryServiceProviderを設定に追加
config/app.php
に
上記で作成したRepositoryServiceProviderを追加して読み込ませる
- config.app.php
'providers' => [
// 省略
App\Providers\RepositoryServiceProvider::class, // 末尾に追加
]
新しく生まれ変わったControllerさん
- ProjectController.php
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Repositories\Project\ProjectRepositoryInterface as ProjectRepository;
class ProjectController extends Controller
{
/**
* @var ProjectRepository
*/
private $projectRepository;
public function __construct(ProjectRepository $projectRepository) {
$this->projectRepository = $projectRepository;
}
/**
* 一覧
*
* @return \Illuminate\Http\JsonResponse
*/
public function index()
{
$projects = $this->projectRepository->getAll();
return response()->json(['projects' => $projects], 200, [], JSON_PRETTY_PRINT);
}
/**
* 新規作成
*
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function store(Request $request)
{
$project = $this->projectRepository->store($request->all());
return response()->json(['project' => $project], 200, [], JSON_PRETTY_PRINT);
}
Laravelにて、Controller側に直接書いてたModel処理をRepositoryに移動した