Home » Code » What are the benefits of using Repositories?

What are the benefits of using Repositories?

Posted by on September 8th, 2014

What are the benefits of using Repositories
So far in this series of blog posts we’ve looked at building and working with Repositories a couple of times.

A Repository is basically a layer that sits between your project’s domain and the database.

Whilst I think The Repository Pattern is becoming pretty well known, it seems to me that there is still confusion over why exactly you would use it, and what the real benefits of it are.

In today’s tutorial I’m going to be looking once again at The Repository Pattern to uncover the real beauty of the design.

Round up of previous examples

Before I jump into the exploration of The Repository Pattern, first we should look back at the two previous posts in this series that also mention the use of Repositories.

The first mention of Repositories was in the post Creating flexible Controllers in Laravel 4 using Repositories. This was the first tutorial that mentioned using a Repository as a layer between your controller and your database. By injecting an instance of an object that implements an interface, we can very easily switch out objects that also implement the same interface.

The next mention of using Repositories was in the post Eloquent tricks for better Repositories. In this post I looked at how you can create an abstract Repository to allow you to reuse common database querying methods. Many of the foundational aspects of a Repository will be consistent from implementation to implementation and so it makes sense to write reusable code.

What are Repositories?

So if you’ve already read those previous posts I’m guessing you are probably already have a fair idea of what a Repository is used for.

But do you understand the real reasons behind using a Repository in the first place? Whilst on the surface the reasoning behind The Repository Pattern seems pretty obvious, I think many people overlook the nuances.

I think there are basically four main benefits of using The Repository Pattern in an application.

Data storage as a detail of the application

The first big benefit of using The Repository Pattern is it moves you closer to thinking about the database as merely a detail of the overall application.

A lot of applications get their first burst of growth through the design of the database schema. Whilst many CRUD-centric applications are very much database oriented, this is the wrong approach for an entirely different suite of applications.

The database is a detail of your application. You should not design your application around how you intend to store the data.

The benefit of using The Repository Pattern in this instance is that you can write the Repository interface at the beginning of the project without really thinking about the actual technical details of how you are going to store your data.

For example, you might have the following UserRepository interface:

interface UserRepository {

  public function findUserById($id);

  public function findUserByUsername($username);

  public function add(User $user);

  public function remove($id);
}

Instead of bothering to set up the database, you can instead write an in memory implementation that simply stores the data in a really lightweight way:

class InMemoryUserRepository implements UserRepository {

  /** @var */
  private $users;

  public function findUserById($id)
  {
    return $this->users[$id];
	}

  public function findUserByUsername($username)
  {
    return array_filter($this->users, function ($user) use ($username) {
      return $this->user->username === $username;
  });
  }

  public function add(User $user)
  {
    $this->users[$user->id] = $user;
  }

  public function remove($id)
  {
     unset($this->users[$id]);
  }
}

You can then continue to build out the real important bits of your application knowing that whenever you get to the point of really needing to store data, you can simply write a Repository implementation that satisfies the requirements of your Repository interface.

Much easier for testing

The second great reason, very much related to the first reason, for using The Repository Pattern is because it make testing your code a lot easier.

Whenever you need to add or query data from the database in your application, instead of hard coding that dependency, you can inject an instance of an object that satisfies the requirements of your Repository interface.

For example, you wouldn’t want to write the following code in your application:

public function find($id)
{
	$repository = new EloquentUserRepository;
	
	return $repository->findUserById($id);
}

By creating a new instance of EloquentUserRepository directly in the method you’ve coupled that dependency to your code.

Instead you should inject an object that meets the requirements of an interface:

public function __construct(UserRepository $repository)
{
  $this->repository = $repository;
}

public function find($id)
{
  return $this->repository->findUserById($id)
}

By injecting an object that satisfies an interface we can very easily inject a different implementation during testing that does not require the test to hit the database:

public function test_find_user()
{
  $repository = new InMemoryUserRepository;
  $controller = new UserController($repository);

  $user = $controller->findUserById(1);

  $this->assertInstanceOf('User', $user);
}

A one-way dependency

Good applications are comprised of a number of different layers that each have a single responsibility within the software stack.

The very top layer is the User Interface. The User Interface is used for displaying data to the user, accepting user input and sending it that input back into the application.

Next we have the HTTP layer that accepts the user input and directs where requests should be sent.

Next we have the application layer that co-ordinates what services we need in order to satisfy the page request.

Next we have the domain layer where the real business logic of the application sits.

And finally at the very bottom we have the database. The database is essentially on the other side of a wall under the domain layer because it’s not really our responsibility.

So as you can see, an application is comprised of a number of different layers. Each of these layers have a single responsibility within the application.

Each layer is also essentially oblivious to the layers below. The User Interface does not care whether the application is written in PHP, Ruby or Java. As long as the HTTP layer can send and receive requests, that’s all that meters.

The HTTP layer does not care about what the Application layer does to satisfy the request. It only cares about sending an appropriate response.

The Application does not care how the Domain layer decides what is considered accepted and what is considered against the business rules, the Application layer has no knowledge of “business rules”.

The Domain layer does not care about how the data is actually stored on the other side of the wall, it only cares about sending and receiving data to satisfy the requests from above.

So as you can see, each layer is totally oblivious to the layers below.

By using The Repository Pattern it allows us to create a one-way dependency between the domain and the data mapping layers.

The in-memory illusion

If we look at the definition of a Repository from the book Patterns of Enterprise Application Architecture we will find the following quote:

Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.

One of the most important characteristics of The Repository Pattern is the fact that it provides a “collection-like” interface.

This means that you should think of accessing the data in your database in the same way you would working with a standard collection object.

The fact that we use databases in applications is really because we need some way of storing the data in a persistence storage, and so it makes sense to use a database.

We should therefore think of the data as if it is stored in a collection, rather than letting the terminology of the database creep into our application.

This means instead of having methods such as save(User $user) we should use add(User $user).

Why is this important? Well at the end of the day we’re still going to be using databases for a long time yet. The fact remains though, that the database should not dictate the design or implementation of your application.

By modelling the interaction with the database as behind the curtain of a collection-like interface we move further away from the database-centric application design that has held us back for so long.

Writing the first repository

A couple of weeks ago we looked at The Specification Pattern.

The Specification Pattern is a way of encapsulating business rules around the selection of objects within an application. In order to “select” those objects, we need a way of querying the database.

In that previous tutorial we injected an interface of UserRepository into the Specification Object.

This is a good example of not allowing the database to hold up progress of the really important bits of the application. We can simply inject an instance of the interface and worry about the database later.

Today we will look at the first tentative steps at writing the UserRepository interface.

Create a new file under Cribbb\Domain\Model\Identity called UserRepository.php:

<?php namespace Cribbb\Domain\Model\Identity;

interface UserRepository {}

Note: I’ve renamed the Users namespace to Identity so the purpose of the code is more explicit. All the code from the last couple of weeks is still there.

The first two methods I will add will be used to find a user by their email address or username. These two methods were required by the Specification object:

/**
 * Find a user by their email address
 *
 * @param Email $email
 * @return User
 */
public function userOfEmail(Email $email);

/**
 * Find a user by their username
 *
 * @param Username $username
 * @return User
 */
public function userOfUsername(Username $username);

The next method I will create will be for adding a new user to the application. I’m going to need this method when I write the code to register a new user.

As I mentioned above, we should think about the Repository as if it were an in-memory collection, rather than a gateway to a database:

/**
 * Add a new User
 *
 * @param User $user
 * @return void
 */
public function add(User $user);

As you can see I’m requiring that an instance of User is passed in. The Repository is responsible for storing and retrieving objects. The Repository is not responsible for taking a raw array of data attributes from the request and creating the User object internally.

And finally I will add a method to return the next identity to use. If you remember back to last week you will know that instead of using auto-incrementing id’s I’m going to be using UUIDs instead.

When you add an item to a collection, it is the collection that is responsible for providing the next identity to be used. Whilst in this case it is not the collection itself that is generating the id, we should conceptually follow the same principle:

/**
 * Return the next identity
 *
 * @return UserId
 */
public function nextIdentity();

You will have noticed that I’m creating the UserRepository right in the heart of the Identity portion of the application’s domain.

The UserRepository is very much part of the application’s business logic. However, the real implementations of the Repository are concerns of the infrastructure.

Therefore when we come to actually writing the implementation for the UserRepository we will house that file under the infrastructure namespace:

<?php namespace Cribbb\Infrastructure\Repositories;

use Doctrine\ORM\EntityRepository;
use Cribbb\Domain\Model\Identity\UserRepository;

class UserDoctrineORMRepository extends EntityRepository implements UserRepository {}

Conclusion

Repositories are important not only on a technical level, but also how we conceptionally think about the different layers of the application.

Using Repositories in our applications has a number of benefits.

Firstly, they prevent you from getting bogged down with the technical details of the infrastructure of the project.

Secondly, they make it much easier to test the various components of the application that interact with the database.

Thirdly, they provide a one-way dependency so the lines between layers are not blurred.

And finally, they provide the illusion of an in-memory collection so that the terminology of the persistent storage does not creep into the language of our applications.

For me, working with repositories just makes the data storage aspect of building web applications a whole lot easier!

This is a series of posts on building an entire Open Source application called Cribbb. All of the tutorials will be free to web, and all of the code is available on GitHub.

To view a full listing of the tutorials in this series, click here.

Philip Brown

Hey, I'm Philip Brown, a designer and developer from Durham, England. I create websites and web based applications from the ground up. In 2011 I founded a company called Yellow Flag. If you want to find out more about me, you can follow me on Twitter or Google Plus.

  • Juukie14

    Nice post, lots of good information!

  • Good article! And it got me thinking in this, instead of using “collection-like” terminology, why not uniquitous language? E.g: A user is added to the system when he is registers, so the method might be called register. Just a thought, what do you think?

  • Tzook Bar Noy

    Everybody talk about the repository but never found one omplamatation the doesn’t return an eloquent object…

    Here you even create an implamantation with doctrine but how would it work, when you pass a User object of eloquent to create a new user?

    And should doctrine return eloquent objects as well??

    • Doctrine is an ORM just like Eloquent is. So if you were writing a Doctrine implementation, it has got nothing to do with Eloquent.

      A Doctrine repository would return a plain PHP object because Doctrine uses The Data Mapper Pattern, whereas Eloquent uses the Active Record Pattern. Have a look at this article http://culttt.com/2014/07/07/doctrine-2-different-eloquent/

      An Eloquent Repository could return the Eloquent object as a plain PHP object or as an array, it doesn’t have to return the Eloquent object.

      • Tzook Bar Noy

        thanks for responding @philip_brown:disqus

        I know that, but as you can see everyone implement it and return an eloquent object…
        so all my views and controllers expect an eloquent…

        and If I would like to return a simple object with the eloquentRepository, how would you handle relationships?

        • You could just call the toArray() method on the Eloquent object to return it as an array. Or you could use a transformer class that would accept the Eloquent object and build a plain PHP object for you.

    • Guest

      Using repositories in Laravel applications is over engineering. Repositories should be used while working with real “dumb” Entities (Doctrine or other DataMappers). Each laravel model is hooked to the db. Adding Repositories for Eloquent models is reverse engineering the ActiveRecord. You’ll probably never ever have to swap out your persistence layer (Laravel does a great job on the different db drivers). And if you have to, it probably wont work anyways, since it’s gonna have a lot of specific implementation logic which will break. So thinking of repositories as of a magic switch that enables you to flip your components on the fly is fairy tales.

      • maximkott

        sorry for the double post

  • maximkott

    Using repositories in Laravel applications is over engineering. Repositories should be used while working with real “dumb” Entities (Doctrine or other DataMappers). Each laravel model is hooked to the db. Adding Repositories for Eloquent models is reverse engineering the ActiveRecord. You’ll probably never ever have to swap out your persistence layer (Laravel does a great job on the different db drivers). And if you have to, it probably wont work anyways, since it’s gonna have a lot of specific implementation logic which will break. So thinking of repositories as of a magic switch that enables you to flip your components on the fly is fairy tales. (Thats my experience)

    • I agree with everything you say.

      However using repositories with Laravel’s Eloquent does make it easier to test as you can switch out the repository implementation with a mock or in-memory implementation.

      But yes, Repositories are best suited to Data Mapped plain PHP objects :)

      • maximkott

        Yes, your are right, using repositories is one way to make testing easier :)

        Btw. I like your articles a lot! Especially the latest ones about Domain Driven Design. Thanks!

  • alireza Rahmani khalili

    I’m working on project has external database which contain 150 tables. what is the best idea to create application ? i mean should i create repository ? and what should i use Eloquent, Query Builder or doctrine?

    • If you have an existing database you will probably be best off using a query builder or data mapper. But to be honest, working on a new application with an existing database probably won’t be that straight forward.

      • alireza Rahmani khalili

        Thanks It means lot to me

  • Gabriel Vieira

    I research a lot this topic and how to implement Repositores in laravel. Everybody says is cool, its abstracts the database and so on. This is possible because you have the IOC and laravel makes the most use of the reflection concept and make that possible. But the only examples i see about this topic is the famous eloquent model that interfaces a repointerface, and we get the classic example of reproducing the findbyid($id) in the implementation that return a the specific model declared on the service provider that you can use later on. So on so good. But, what about the rest? How to do full implementations logics with the repositores, not just CRUD operations.
    Where to put the business logic? in the model, in the repo implementation, in a service layer? And here, is where all the discuss about this topic fails to delivery an example. If you use repos and related design concepts, than you should interface everything on your business logic, application logic etc…. For me it was the only away to do full implementations without break dependencies. Packages are cool, where to put it, how to use it and glue them to your application. Should i use the bindinds on in every class extend our use the “use” all over the place, I learned a lot with the research i have done especially in culttt, but for beginners they simply dont have a A to Z guide in this context or best practices. Cheers

    • Thanks Gabriel :) Sounds like you should read my new posts on using Doctrine 2 and a more Domain Driven Design approach to building Cribbb http://culttt.com/tag/cribbb/

      • Gabriel Vieira

        Hi Philip, believe me that i have been read your post :). Its the best resources i have found on the about domain driven design in laravel. thanks for the great work!

  • jdubwelch

    What’s the best approach for updating date when using the repository pattern?


    public function update($id, array $data)
    {
    // get the model
    // update the model
    // save the model
    // return the model
    }

    • Yeah I’ve used basically that exact same procedure before, so that would work :)

  • Kanat Tabaldiev

    Why is quick switch of implementation pointed as a Benefit – if it is not possible? When you switch Eloquent Repository to another type – it will return different type of model object inside the collection which will be impossible to use…
    Or am I getting something wrong?

    • It is possible, as long as the returned model object has the same API it will work.

      • Kanat Tabaldiev

        Ok, now please correct me if I get it wrong. Controller, Repository, Factory other services – all are like workers each of them having its own responsibility, view is like some kind of Product that we are building, and models are details (or building materials) of this product. The benefit of quick switching implementations – is like we can easily replace one worker with another that can solve same responsibilites, and if models have different API then our previous model that means that the details of the house that we are building don’t meet the specs for that house, and workers should not be blamed for this, so we can just add one more service layer or something, that will convert the model objects to have the API like old models.

        • Hmm, I’m not sure I 100% understand what you mean, but yeah you just have to ensure the interface of the model does not change because the “workers” are expecting the model object to have certain methods.

  • ercobot

    Very nice post Philip.But what if you want to use the findUserById() function but from different database?Would you make a new DB class extends UserRepository with implementation of the findUserById() there?

    • Thank you :)

      Hmm, yeah I guess so. You could probably get away with having it in the same UserRepository as the implementation is hidden away from the interface.