実務で使うべきか?どう実装するか?
LaravelはEloquentが非常に優秀なので、
「Repositoryって本当に必要?」という議論がよく起きます。
結論から言うと:
- 小規模 → 不要なことが多い
- 中〜大規模 → かなり有効
この記事では実装ベースで整理します。
1. Repositoryパターンとは?
データアクセスの責務を分離する設計。
ControllerやServiceが直接Eloquentを触らないようにします。
2. ディレクトリ構成例
app/
├─ Models/
├─ Repositories/
│ ├─ PostRepositoryInterface.php
│ └─ PostRepository.php
├─ Services/
└─ Http/Controllers/
3. Interface作成
app/Repositories/PostRepositoryInterface.php
namespace App\Repositories;
use App\Models\Post;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
interface PostRepositoryInterface
{
public function paginate(int $perPage = 15): LengthAwarePaginator;
public function find(int $id): ?Post;
public function create(array $data): Post;
public function update(Post $post, array $data): Post;
public function delete(Post $post): void;
}
ポイント:
- 実装ではなく「契約」を定義する
- ControllerはInterfaceに依存する
4. 実装クラス
app/Repositories/PostRepository.php
namespace App\Repositories;
use App\Models\Post;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
class PostRepository implements PostRepositoryInterface
{
public function paginate(int $perPage = 15): LengthAwarePaginator
{
return Post::latest()->paginate($perPage);
}
public function find(int $id): ?Post
{
return Post::find($id);
}
public function create(array $data): Post
{
return Post::create($data);
}
public function update(Post $post, array $data): Post
{
$post->update($data);
return $post;
}
public function delete(Post $post): void
{
$post->delete();
}
}
5. ServiceProviderでバインド
app/Providers/AppServiceProvider.php
use App\Repositories\PostRepository;
use App\Repositories\PostRepositoryInterface;
public function register(): void
{
$this->app->bind(
PostRepositoryInterface::class,
PostRepository::class
);
}
これでDI可能になります。
6. Service層で利用
app/Services/PostService.php
namespace App\Services;
use App\Models\Post;
use App\Repositories\PostRepositoryInterface;
class PostService
{
public function __construct(
private PostRepositoryInterface $postRepository
) {}
public function create(array $data): Post
{
return $this->postRepository->create($data);
}
}
7. Controllerは薄く保つ
public function store(StorePostRequest $request)
{
$post = $this->postService->create($request->validated());
return new PostResource($post);
}
8. メリット
- テストでMock差し替え可能
- DB変更に強い
- 責務分離が明確
- クエリが肥大化しても整理できる
9. デメリット
- ファイル数が増える
- 小規模開発では冗長
- Eloquentが既に抽象化なので二重抽象になる場合もある
10. 実務的な判断基準
導入すべきケース:
- チーム開発
- クエリが複雑
- 将来DB変更の可能性がある
- テストをしっかり書く
不要なケース:
- CRUD中心の小規模API
- 一人開発のプロトタイプ
まとめ
Repositoryは「絶対必要」ではないです。
でも設計が成長するプロジェクトでは、
確実に効いてきます。
導入は“規模”で判断するのが現実的です。