I'm not a big fan of the repository pattern in Laravel apps, even in a big ones – when working in a team. It's a hard concept to do right. If done wrong it does more harm than good; it's hard to maintain, hard to refactor and hard to change behaviour. Laravel has a great way to write custom query builders to extract business logic. Great for querying models. For writing models I would suggest using Action Closes. One example of them can be found in Jetstream's sourcecode . Actions are great to test in isolation and link to user stories. Answer from Becksteen on reddit.com
🌐
Reddit
reddit.com › r/laravel › is using the repository pattern best practise?
r/laravel on Reddit: Is using the repository pattern best practise?
January 29, 2023 -

Is using the repository pattern best practise?

What's the size, scope, experience, need for performance/scaling etc. required to determine the approach/pattern for development to avoid code smell?

Repositories are common & I haven't seen a convincing alternative. I have read about Onion architecture, which is basically the repository pattern with a service layer between the repository & controller. For developers using PHP/Laravel, Whats you take and experience on this?

🌐
Medium
soulaimaneyh.medium.com › laravel-repository-pattern-da4e1e3efc01
PHP Laravel Repository Pattern. The Repository Pattern is a software… | by Soulaimane YAHYA | Medium
February 28, 2025 - PHP Laravel Repository Pattern The Repository Pattern is a software design pattern that separates the application logic from the underlying data storage layer. It provides an abstraction layer …
Discussions

In Laravel’s Repository pattern, should I pass an Eloquent model (User $user) or a DTO to keep it framework-agnostic? - Stack Overflow
I’m refactoring my Laravel application to follow a clean architecture approach with clear separation of concerns: Controller → Service → Repository The Controller handles the HTTP layer,the Service More on stackoverflow.com
🌐 stackoverflow.com
php - how to implement Repository Pattern In Laravel - Stack Overflow
Although there Are some Tutorials on medium and some other sites about the Repository pattern for Laravel I read in some sites that repository pattern will duplicate the ORM and You won't need it in More on stackoverflow.com
🌐 stackoverflow.com
oop - Managing relationships in Laravel, adhering to the repository pattern - Stack Overflow
While creating an app in Laravel 4 after reading T. Otwell's book on good design patterns in Laravel I found myself creating repositories for every table on the application. More on stackoverflow.com
🌐 stackoverflow.com
Laravel – Using Repository Pattern

Generally good info but a couple of gripes...

The interface name, why not call the interface UserRepositoryInterface rather than the "I" prefix or even just UserRepository? Then name the implementation "EloquentUserRepository" and bind the interface to that, it's a bit more explicit that way.

For the sake of reusability and maintaining a narrower scope for your controllers, inject the repository as a variable called $repository rather than $user. This easily leads you to discovering a pattern of more resource based controllers that don't necessarily have to be unique.

Inject or otherwise have the repository depend on a model or query builder. Just randomly constructing a new user via the Facade in the repository is not good practice.

IMO repositories should be reserved strictly for CRUD operations. The next logical thing a developer may want to do based on your example is sort and filter the list. That logic should live in a list or index service/repository that gets injected into your controller, not necessarily in a CRUD repo that represents the user model. If you consider repositories as being the resources for RESTful controllers, a URL like domain.com/users should have it's own controller and repository versus a URL like domain.com/users/<id>. Each of those URLs should have separate controller actions for each http verb. E.g. - GET /users and GET /users/<id>.

More on reddit.com
🌐 r/laravel
2
15
April 18, 2014
🌐
Twilio
twilio.com › en-us › blog › repository-pattern-in-laravel-application
How to Use the Repository Pattern in a Laravel Application | Twilio
January 26, 2024 - Modern PHP frameworks, such as Laravel and Symfony, interact with databases via Object-relational mappers (ORMs); Symfony uses Doctrine as its default ORM and Laravel uses Eloquent. Both take different approaches in how database interaction works. With Eloquent, Models are generated for each database table, forming the basis of interaction. Doctrine, however, uses the Repository pattern where each Entity has a corresponding repository containing helper functions to interact with the database.
🌐
OneUptime
oneuptime.com › home › blog › how to implement repository pattern in laravel
How to Implement Repository Pattern in Laravel
February 3, 2026 - The repository pattern sits between your application logic and your data layer. It gives you a clean API for data access while hiding the implementation details - whether you're using Eloquent, raw SQL, or an external API.
🌐
Laravel Daily
laraveldaily.com › lesson › design-patterns › repository-pattern
10 - Repository Pattern: Why I Don't Recommend It | Laravel Daily
As I understand it the purpose of a repository is to provide a data access layer between the business logic and the database (models), so (taking a as an example Orders, and Order lines which would be separate models) you might have a single Order repository to handle as an integrated whole the access to existing, and creation of new, orders with their associated order lines, ensuring for example, that creation of an Order has insertion of an order record and associated order lines as part of an atomic transaction, and that the created Order is a valid one (e.g.
🌐
Medium
medium.com › @rluders › your-laravel-application-with-repository-doesnt-make-any-sense-ab2ae1bf044b
Your Laravel application with Repository doesn't make any sense | by Ricardo Lüders | Medium
July 31, 2024 - In conclusion, while the Repository pattern and clean architecture principles offer significant benefits in terms of maintainability and separation of concerns, their application in a Laravel context often introduces unnecessary complexity.
Find elsewhere
🌐
DEV Community
dev.to › blamsa0mine › structuring-a-laravel-project-with-the-repository-pattern-and-services-11pm
Structuring a Laravel Project with the Repository Pattern and Services 🚀 - DEV Community
November 21, 2024 - This article explores these concepts with practical examples to help you build a clean, testable, and maintainable Laravel project. The Repository Pattern provides an abstraction layer between the database and the business logic of your application.
🌐
Abdelrahman Etry
abdelrahmanetry.com › article › 46 › laravel-repository-pattern
Blog - Laravel Repository Pattern
The Laravel Repository Pattern is a powerful architecture design that separates data access logic from presentation logic, providing developers with an easy-to-use and scalable way to manage their data.
🌐
Cubet
cubettech.com › resources › blog › introduction-to-repository-design-pattern
Repository Design Patterns | Laravel development
June 19, 2023 - A repository is simply an interface between two things. So instead of referencing Eloquent directly, we can reference UserRepository. We can then bind UserRepository to EloquentUserRepository so that Laravel knows that whenever we mention ...
🌐
Kritim Yantra
kritimyantra.com › blogs › laravel-repository-pattern-explained
Laravel Repository Pattern Explained: Clean Architecture for Developers - Kritimyantra | Blog
As your Laravel application grows, you might notice that your controllers start filling up with database queries and business logic. This can make your code messy, hard to maintain, and tricky to test. That’s where the repository pattern comes in—a simple yet powerful design pattern that helps keep your code organized by separating the data access layer from your business logic.
Top answer
1 of 4
279

I am finishing up a large project using Laravel 4 and had to answer all of the questions you are asking right now. After reading all of the available Laravel books over at Leanpub, and tons of Googling, I came up with the following structure.

  1. One Eloquent Model class per datable table
  2. One Repository class per Eloquent Model
  3. A Service class that may communicate between multiple Repository classes.

So let's say I'm building a movie database. I would have at least the following following Eloquent Model classes:

  • Movie
  • Studio
  • Director
  • Actor
  • Review

A repository class would encapsulate each Eloquent Model class and be responsible for CRUD operations on the database. The repository classes might look like this:

  • MovieRepository
  • StudioRepository
  • DirectorRepository
  • ActorRepository
  • ReviewRepository

Each repository class would extend a BaseRepository class which implements the following interface:

interface BaseRepositoryInterface
{
    public function errors();

    public function all(array $related = null);

    public function get($id, array $related = null);

    public function getWhere($column, $value, array $related = null);

    public function getRecent($limit, array $related = null);

    public function create(array $data);

    public function update(array $data);

    public function delete($id);

    public function deleteWhere($column, $value);
}

A Service class is used to glue multiple repositories together and contains the real "business logic" of the application. Controllers only communicate with Service classes for Create, Update and Delete actions.

So when I want to create a new Movie record in the database, my MovieController class might have the following methods:

public function __construct(MovieRepositoryInterface $movieRepository, MovieServiceInterface $movieService)
{
    $this->movieRepository = $movieRepository;
    $this->movieService = $movieService;
}

public function postCreate()
{
    if( ! $this->movieService->create(Input::all()))
    {
        return Redirect::back()->withErrors($this->movieService->errors())->withInput();
    }

    // New movie was saved successfully. Do whatever you need to do here.
}

It's up to you to determine how you POST data to your controllers, but let's say the data returned by Input::all() in the postCreate() method looks something like this:

$data = array(
    'movie' => array(
        'title'    => 'Iron Eagle',
        'year'     => '1986',
        'synopsis' => 'When Doug\'s father, an Air Force Pilot, is shot down by MiGs belonging to a radical Middle Eastern state, no one seems able to get him out. Doug finds Chappy, an Air Force Colonel who is intrigued by the idea of sending in two fighters piloted by himself and Doug to rescue Doug\'s father after bombing the MiG base.'
    ),
    'actors' => array(
        0 => 'Louis Gossett Jr.',
        1 => 'Jason Gedrick',
        2 => 'Larry B. Scott'
    ),
    'director' => 'Sidney J. Furie',
    'studio' => 'TriStar Pictures'
)

Since the MovieRepository shouldn't know how to create Actor, Director or Studio records in the database, we'll use our MovieService class, which might look something like this:

public function __construct(MovieRepositoryInterface $movieRepository, ActorRepositoryInterface $actorRepository, DirectorRepositoryInterface $directorRepository, StudioRepositoryInterface $studioRepository)
{
    $this->movieRepository = $movieRepository;
    $this->actorRepository = $actorRepository;
    $this->directorRepository = $directorRepository;
    $this->studioRepository = $studioRepository;
}

public function create(array $input)
{
    $movieData    = $input['movie'];
    $actorsData   = $input['actors'];
    $directorData = $input['director'];
    $studioData   = $input['studio'];

    // In a more complete example you would probably want to implement database transactions and perform input validation using the Laravel Validator class here.

    // Create the new movie record
    $movie = $this->movieRepository->create($movieData);

    // Create the new actor records and associate them with the movie record
    foreach($actors as $actor)
    {
        $actorModel = $this->actorRepository->create($actor);
        $movie->actors()->save($actorModel);
    }

    // Create the director record and associate it with the movie record
    $director = $this->directorRepository->create($directorData);
    $director->movies()->associate($movie);

    // Create the studio record and associate it with the movie record
    $studio = $this->studioRepository->create($studioData);
    $studio->movies()->associate($movie);

    // Assume everything worked. In the real world you'll need to implement checks.
    return true;
}

So what we're left with is a nice, sensible separation of concerns. Repositories are only aware of the Eloquent model they insert and retrieve from the database. Controllers don't care about repositories, they just hand off the data they collect from the user and pass it to the appropriate service. The service doesn't care how the data it receives is saved to the database, it just hands off the relevant data it was given by the controller to the appropriate repositories.

2 of 4
74

Keep in mind you're asking for opinions :D

Here's mine:

TL;DR: Yes, that's fine.

You're doing fine!

I do exactly what you are doing often and find it works great.

I often, however, organize repositories around business logic instead of having a repo-per-table. This is useful as it's a point of view centered around how your application should solve your "business problem".

A Course is a "entity", with attributes (title, id, etc) and even other entities (Assignments, which have their own attributes and possibly entities).

Your "Course" repository should be able to return a Course and the Courses' attributes/Assignments (including Assignment).

You can accomplish that with Eloquent, luckily.

(I often end up with a repository per table, but some repositories are used much more than others, and so have many more methods. Your "courses" repository may be much more full-featured than your Assignments repository, for instance, if your application centers more around Courses and less about a Courses' collection of Assignments).

The tricky part

I often use repositories inside of my repositories in order to do some database actions.

Any repository which implements Eloquent in order to handle data will likely return Eloquent models. In that light, it's fine if your Course model uses built-in relationships in order to retrieve or save Assignments (or any other use case). Our "implementation" is built around Eloquent.

From a practical point of view, this makes sense. We're unlikely to change data sources to something Eloquent can't handle (to a non-sql data source).

ORMS

The trickiest part of this setup, for me at least, is determing if Eloquent is actually helping or harming us. ORMs are a tricky subject, because while they help us greatly from a practical point of view, they also couple your "business logic entities" code with the code doing the data retrieval.

This sort of muddles up whether your repository's responsibility is actually for handling data or handling the retrieval / update of entities (business domain entities).

Furthermore, they act as the very objects you pass to your views. If you later have to get away from using Eloquent models in a repository, you'll need to make sure the variables passed to your views behave in the same way or have the same methods available, otherwise changing your data sources will roll into changing your views, and you've (partially) lost the purpose of abstracting your logic out to repositories in the first place - the maintainability of your project goes down as.

Anyway, these are somewhat incomplete thoughts. They are, as stated, merely my opinion, which happens to be the result of reading Domain Driven Design and watching videos like "uncle bob's" keynote at Ruby Midwest within the last year.

🌐
Doeken
doeken.org › doeke norg | php architect | legacy modernization › blog › the infamous repository pattern in php
The infamous Repository Pattern in PHP | doeken.org
January 25, 2024 - In this pattern you create a single findBy(Criteria $criteria) method which retrieves all objects that satisfy the criteria. While this may look like a great one-size-fits-all solution, you have to be careful not to be creating a Query Builder. Because for every Criteria you create, you need an implementation that is compatible with your repository's underlying data source.
🌐
DEV Community
dev.to › kasenda › use-repository-pattern-with-laravel-e8h
Use Repository Pattern with Laravel - DEV Community
December 11, 2022 - Modern PHP frameworks, such as Laravel and Symfony, interact with databases via Object-relational mappers (ORMs); Symfony uses Doctrine as its default ORM and Laravel uses Eloquent. Both take different approaches in how database interaction works. With Eloquent, Models are generated for each database table, forming the basis of interaction. Doctrine, however, uses the Repository pattern where each Entity has a corresponding repository containing helper functions to interact with the database.
🌐
Codecourse
codecourse.com › courses › the-repository-pattern-in-laravel
The Repository Pattern in Laravel
Avoid repetition, scale your project and make maintenance a cinch. From simple to powerful repositories that work for any size project, we go through the steps to implement the repository pattern in Laravel.
🌐
Laracasts
laracasts.com › discuss › channels › eloquent › models-repository-pattern-and-eloquent
Models, repository pattern and Eloquent
To answer your create method question, utilizing repository pattern and the command bus pattern together. The command bus is to perform the create and update implementation and execution. So in your controllers you execute the command instead of using creating that method in the repository. If implemented per the structure which isn't laravel specific it will in effect perform the create and or update method.