Skip to main content

Experience with Repository pattern implementation in Laravel

Hi folks,

Today I am gonna be sharing my experience of implementing and working with Repository Design Pattern in Laravel.

As you must be aware that Repository Pattern is one of the widely used design patterns 
"which separates the logic that retrieves the data and maps it to the entity model from the business logic that acts on the model. In other words, business logic can access the data object without having knowledge of the underlying data access architecture"

My first hand experience

Around a year ago I started working on a Service Provider App with Laravel as the back-end exposing APIs for the front-ends like the Mobile and Desktop Apps.

And like any other architect, while designing this huge looking application I had to take some important decisions on the architectural level. One of them being the buzzing, totally in, Repository Design Pattern bandwagon which everybody in the tech world was taking and if not that, at-least talking about.

I went through lots of tutorials, forums, reddit discussions, webcasts etc to make sure I had enough information required to take this decision.

And after digging for about a week or so, I decided to implement the much discussed Repository Pattern in the Laravel App(of course, the prettus/l5-repository).

Although it seemed like a lot of effort considering we needed the following
  • Repository Interfaces,
  • Transformers, 
  • Presenters, 
  • and Repositories themselves
extra whenever we required to add a new Model in the application; multiply this with the number of different Databases we need to connect, if at all; we kind of started getting used to of it considering the advantages.

There was this whole talk about live Database switch if we use the Repository Patterns and I was really excited about the futuristic edge that this decision of mine has given us. I told my partner(and main founder of the company) about these benefits, and told him that we can do all kind of stuff by plugging in systems like Mongo, Hadoop, Elasticsearch and what not with very minimal config changes, without any code changes and everything on-the-fly. We surely were excited.

Its been around 10 months now since we have been working on the APP, along with the Repository Pattern and I have had my share of experiences with it which I am gonna put down here in this post, so maybe somebody out there still trying to make this decision can take help from my experiences.

Details and work-flow

So this is how the flow with Repositories work
  1. We create the repository and all the other required files
  2. In the repository we define the model linked to it, and the presenters also. This repository has all the functions of the RepositoryInterface implemented.
  3. The next step is binding(maybe in the AppServiceProvider class), you bind the RepositoryInterface implementation with the Repository of the DB system you want(in my case there was only one Repository because we are using Postgres). So maybe you have MongoDBUserRepo and PostgresUserRepo and UserRepoInterface is binded with either of them based on the current requirement.
  4. This makes the specific Repository class and whenever the UserRepoInterface is passed in a controller constructor either Mongo or Postgres repository is injected (based on the binding condition).
  5. Now we have a Repository layer in place which hides the actual DB related implementation behind the scenes and which is bound by the repository interface to implement all the required functions.

Merits and De-merits

Lets now look at what all are we achieving by doing so and what all will we be loosing on.

Merits

The plus points first, and there are quite some of them -
  1. No code style change - For the developers benefit, they return Eloquent Objects, which means the current code would not break. You don't have to learn new coding syntaxes when working it(at least the prettus one does, if you want you could return whatever you prefer, an array perhaps).
  2. DB Swapping - It makes switching between DBs breeze. You just have to put proper binding of the required DBRepository and all the subsequent RepositoryInterface objects will return that DBRepository.
  3. Separation on concerns and re-usability - Controllers take care of the business logic and the repositories take care of the data delegation to the actual DB source(like models).
  4. TDD - Make a MockRepository(based on Mockery or something similar) and you can do your testing by binding the MockRepository based on some environment/config variable.

Disadvantages

  1. Lots of code - As you can see we are just adding multiple set of files to achieve something which we could have done by using the Models(Eloquent) and the Controllers only. Yea there would be some DB related code in the Controllers but you could probably use Collections and Mutators wherever possible and keep the Controllers slim
  2. Little over-hyped - We talk a lot about DB switching, but in almost all the use cases we have a single DB which serves as the System of records and then we have other supportive DBs which are either meant for analysis, caching, archiving etc. This can be easily achieved by Observers. You simply observe create/update/delete on any models and replicate the required data to another Data Source. And then use separate classes(perhaps Repositories if there are multiple source types) to access this DB data as and when required.
  3. Extra layer on top of ORM - By implementing Repositories we are only adding another layer on top of Eloquent which itself is a ORM/Active Record layer. So in most use cases it becomes an overkill
  4. Added complexity - We are adding more complexity on an already complex system. Now to even implement lets say caching, we might have to various Database calls on other data sources as well.
So far, as per my personal experience goes, I wasn't really benefited from Repository pattern. For me it has proved to be an extra effort and lines of code. However, Transformers per say, were really helpful in organizing the data I wanted to send back in my API responses.
I feel, in my project, Observers are doing the job for me, as I can observe specific models and update my other databases like Elasticsearch data based on them and then use the ESDataRepository to get the desired functionality.

I hope I was able to help you with my experiences here and clear some doubts about Repository pattern implementation in Laravel in the process.

Cheers,
Sandeep Rajoria

P.S. -  Get quick data insights and explanatory visualizations via various charting options through my charting App

Comments

Tiago A. said…
Great article. Similar to my experience too...

Btw, did you see this article? https://adamwathan.me/2015/02/14/active-repository-is-an-anti-pattern/
Adam Wathan argues that the Repository Pattern only makes sense when using data mapper and not AR (like Eloquent).

Another problem I found is having to fight the temptation of using all the Eloquent goodies (relations, scopes, computed attributes, etc) that would "go around" the repository, when the repository returns Eloquent models.
Sandeep Rajoria said…
Thanks Tiago for the comment and the article. It was a good read and made total sense to me, and after my experience with Repository pattern I feel the same way that you dont really benefit in most of the scenarios with this pattern.

My experience is also exactly the same with repository pattern and now as the application is in continuous maintenance mode it's a pain.

As Tiago mentioned using AR it's almost impossible to implement it academic way. I also had a look on doctrine but can't buy it against mighty Eloquent

Great post
Helptoinstall said…
It’s great to come across a blog every once in a while that isn’t the same out of date rehashed material. Fantastic read. Best magneto migration service service provider.

Popular posts from this blog

Multi Tenancy with Codeigniter

In this post I will show you how I converted my normal Codeigniter application into a multi-tenant system.(first step to a SaaS implementation) Note - This implementation is a separate DB multi-tenancy implementation. Lets say we have an up and running CI application name ci_app , with the directory structure like this ./application ./application/config ./application/...so many other important directories ./asset ./asset/js ./asset/images ./asset/css ./system ./index.php which is accessed through browser like http://localhost/ci_app So to implement the multi-tenant arch we are most concerned about the following files, and we will be editing them ./index.php ./application/config/config.php ./application/config/database.php And also we need to create a few new ones Create a tenant folder in your www root directory, lets say tenant_1 Cut the ./index.php from ci_app and paste it in tenant_1 directory  Create a blank file config.php in tenant_1 directory Crea

Profiling and checking PHP error_reporting in a Codeigniter App, without editing the config!!

Hi all, You must have definitely used the Profiling in Codeigniter and error_reporting many a times in Development and Testing environment, but I am sure you must have missed it on a real Production environment. As there are scenarios, where you want to quickly debug the Production application and find out what PHP errors is the application throwing, check the page profile, that too without putting the time and effort in replicating the whole production environment on your local machine, or perhaps a testing server. This small piece of code(we could perhaps call it a hack), which I have used in almost all of my CI applications, will make your life very easy, without losing anything on the security of the system. Following points, essentially sum up what exactly it does - Check for the dev(or root or admin, whichever name you use for the su access), if it is logged in, as we don't want others to see all the Profile data and other errors. Check for a specific query str