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"
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
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.
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
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
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- We create the repository and all the other required files
- In the repository we define the model linked to it, and the presenters also. This repository has all the functions of the RepositoryInterface implemented.
- 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.
- 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).
- 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 -- 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).
- 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.
- 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).
- 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
- 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
- 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.
- 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
- 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.
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
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.
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