0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LaravelでRepositoryパターンを実装する

0
Posted at

実務で使うべきか?どう実装するか?

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は「絶対必要」ではないです。

でも設計が成長するプロジェクトでは、
確実に効いてきます。

導入は“規模”で判断するのが現実的です。


0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?