DEV Community

Abdul Muiz
Abdul Muiz

Posted on

Does repository pattern make sense when using it in Laravel?

I mean the main purpose of repository pattern is to abstract the database layer like this:

Respository Pattern

But I think it is already done by Eloquent. What do you think about it?

Top comments (8)

Collapse
 
eduardort profile image
Eduardo Reyes

The repository pattern and Eloquent are not competitors, you can use Eloquent inside a repository, it's particularly useful when you need more functionality that makes the Eloquent Query weird, it can also make your code more legible with stuff like getAdmins or getActiveUsers instead of the direct query – also, having the query in one place instead of multiple will allow you to reduce errors

If you don't need to re-use the queries then a Repository is overkill anyway – Even though, it can still provide value depending on the complexity of the queries.

I've seen it used in Laravel apps before, in conjunction with the Service Pattern, this was a massive codebase though.

YAGNI and KISS always in mind!

Collapse
 
ben profile image
Ben Halpern

Rails works the same way, where ActiveRecord already acts as the standard object mapping on top of the database. But I saw a talk where someone described eschewing ActiveRecord for the repository pattern and it was working just fine for them.

I don't remember all the details, but my thoughts are that this is probably totally possible, but if Laravel is anything like Rails, swimming against the current is just a little awkward. You won't be facing the same problems as most of the rest of the community.

The repository pattern seems like a wonderful approach, but I wouldn't break from the framework's norm without a lot of conviction for doing so.

Would love to see some answers from folks with more insight into these things.

Collapse
 
muizabdul29 profile image
Abdul Muiz • Edited

@ben Yep. I was thinking the same to avoid it. I tried to implement the repository class and it looked like this:

class UserRepository implements RepositoryContract
{
    public function save(User $user)
    {
        $user->save();

        return $user;
    }

    public function getBy($value, $by = 'id', $fields = '*')
    {
        if (is_null($value)) {
            return;
        }
        return User::select($fields)->where($by, $value)->first();
    }

    public function remove(User $user)
    {
        // remove it here
    }
}
Enter fullscreen mode Exit fullscreen mode

Apart from the flexibility that getBy method gives, there does not seem to be any reason to follow this approach. This link also seems to be very helpful regarding this.

Collapse
 
aacsssh profile image
Aashish Ghale

In my understanding, this is not how Repository Pattern works. If you create a Repository class in Laravel then you should never return Eloquent models from that class because it makes your whole application depended on Eloquent. You may ask how?

By returning Eloquent models, we end up using many Eloquent related functions in our controllers or views. For example, if you want paginated data then you end up using LengthAwarePaginator's functions to get information like total pages, total data, current page and others. There are other scenarios which you may be well aware of if you are into Laravel.

What if in future for some reason, you want to ditch Eloquent and use other ORMs? You expect your application to run smoothly after the switch but it won't because your controllers and views are dependent on the functions that were provided via Eloquent. Your application is tightly coupled with Eloquent. Instead of returning Eloquent, you should return domain object. Please read "Patterns of Enterprise Application Architecture" by Martin Fowler for more information on this.

Saying all this, in my experience, I don't see any benefits of using Repository class in Laravel. I have not seen anyone ditching Eloquent in favour of other ORMs. If you have valid reason to switch then repository pattern may help but you have to design it well at first.

If you are sticking with Eloquent then why add an extra layer? If you really want a place where you can create nice APIs for long queries that requires multiples query builder functions then you can define it in model itself by astracting the methods in a trait and using it model and use it in some Service class accordingly.

Collapse
 
awesdotio profile image
Awes.io • Edited

We have built a PHP package for Laravel and use it for our projects.
Please check it out!
github.com/awes-io/repository

Repository