Laravel Repository Pattern

이하루·2024년 8월 3일

Laravel에서 데이터 엑세스를 추상화하는 디자인 패턴인 Repository Pattern을 적용해 보도록 한다.

🔎 Repository Pattern이란?

Repository Pattern은 간단히 말하자면, 데이터 출처에 관계 없이 동일한 인터페이스로 데이터에 접근할 수 있도록 만드는 것이다. 이 패턴을 적용시키면 Model은 Repository에 데이터를 요청해서 받아올 수 있기 때문에, Model은 데이터의 출처(로컬/서버)나 방식에 대해서 알 필요가 없어지며 순전히 비즈니스 로직에만 집중할 수 있게 된다.

장점

  1. 코드 재사용성
    엑세스 로직을 캡슐화시킴으로써 동일한 방식의 엑세스 로직을 필요로 하는 경우, 코드를 재사용하기 쉽다.

  2. 데이터 엑세스의 추상화
    엑세스 로직의 추상화를 통해 데이터의 세부 정보를 비즈니스 로직으로부터 분리시킬 수 있다. 이로 인해, 데이터를 받아오는 방법을 변경하더라도 애플리케이션의 다른 부분의 영향을 미치지 않는다.

단점

로직을 분리함으로써, 그만큼 독립성/재사용성이 상승했다는 장점도 있지만 그에 반해 유지보수할 곳이 더 늘어난다는 점과 복잡성이 늘어나므로 새로 들어온 멤버의 코드 이해의 시간이 더 걸릴 가능성이 높다.

✅ Laravel에서의 Repository Pattern

Repository Pattern의 핵심이 되는 엑세스 로직의 분리를 위해 Laravel에서는 app\Repositories라는 디렉토리를 권장한다.

  1. 우선, 해당 디렉토리에 repository 인터페이스를 아래와 같이 생성한다.
namespace App\Repositories;

interface UserRepositoryInterface
{
    public function getAllUsers();
    public function findUserById($id);
    public function createUser(array $data);
}
  1. 인터페이스를 구현하기 위한 repository 클래스 또한 동일한 위치에 작성한다.
namespace App\Repositories;
use App\Models\User;
class UserRepository implements UserRepositoryInterface
{
    public function getAllUsers()
    {
        return User::all();
    }

    public function findUserById($id)
    {
        return User::find($id);
    }

    public function createUser(array $data)
    {
        return User::create($data);
    }
}
  1. 서비스 프로바이더에서 Repository 인터페이스를 Repository 클래스를 통해 확장(바인딩)해 준다.
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Repositories\UserRepositoryInterface;
use App\Repositories\UserRepository;

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->bind(UserRepositoryInterface::class,
			UserRepository::class);
    }
}
  1. use키워드를 통해 Repository 인터페이스의 사용을 선언하고, 확장한 인터페이스를 활용해 데이터에 접근할 수 있다.
namespace App\Http\Controllers;

use App\Repositories\UserRepositoryInterface;

class UserController extends Controller
{
    protected $userRepository;

    public function __construct(UserRepositoryInterface $userRepository)
    {
        $this->userRepository = $userRepository;
    }

    public function index()
    {
        $users = $this->userRepository->getAllUsers();
        return view('users.index', compact('users'));
    }
}
profile
어제보다 더 나은 하루

0개의 댓글