Repositories vs No Repositories in Laravel

My thoughts about using repositories in a Laravel application.

Posted by Igor Randjelovic on April 4, 2015

Repositories vs No Repositories

I always thought decoupling is a good thing but there are cases where you think you are decoupling when in fact, you are just adding a new layer to the coupled code.

Let’s see an example, say you have a typical CRUD application, a blog (simple example, applies even more to more complex cases). You have Posts, Categories, and Tags let’s say. With eloquent it’s pretty easy to set the relations up and use them.

You want to be proficient with your code, and you create a PostRepository interface and others (Tag / Category). Then you proceed to create an concrete implementation for Eloquent, and you just “map” those common methods to eloquent.

class EloquentPostRepository implements PostRepositoryContract {

   ...
   public function all()
   {
       return $this->post->all();
   }
   ...

}

Essentially you are returning an eloquent instance through your repository, and that’s fine, but what if you want to use relations? It’s easy, $post->tags();. Perfectly fine, and easy.

Time goes by, and you now need to swap out eloquent with mongodb. What do you do? Create a new Class, make sure it implements your repository interface, add all the methods, write the mongodb implementation, and change the binding in the IoC container, and last but not least you cross your fingers.

Fire up your app, and you are welcomed by errors like Method tags() does not exists. What?! How is that possible? I used repositories, my app should not break!? What do I tell my boss about this? How do I fix this?

All these questions…

Can this be solved?

Absolutely, you can write DTO’s for your data (models) and use those from your repositories. But in that case, it’s much harder to deal with relations. It’s so much extra work.

Is it worth the extra work?

In some cases, yes, but most of the time, there is a good chance you won’t need to change to a database that’s not supported by eloquent.

I personally don’t use repositories anymore, since they are just an extra layer that doesn’t serve anything. I’d rather just inject my model through the constructor, and use it directly, and my code remains testable (no facades). I can still mock the Model, and make sure methods were called etc.