Introduction to Repository Pattern with Laravel 5

In the Repository Pattern we create a layer between the data access logic and the business logic. You can use this approach to overcome the problem of having data and business logic in the controller.

The result of a traditional MVC approach generally is “dirty” controllers. In practical terms, it means that there is a lot going on in the controller, making it hard to test, scale and reuse the components.

This tutorial is an introduction to the Repository Pattern with Laravel. I assume that you are familiar with the basic of Laravel and concepts such as Inheritance and Interface.

You can also check the full code on Github.

Repository Pattern with Laravel – Workflow

In this tutorial we will be creating a simple task app through the following steps:

  • Setup our app and database connection;

  • Organizing folders and files;

  • Creating the interface;

  • Implementing the interface;

  • Binding interface with implementation;

  • Calling the methods in the controller;

  • Defining routes;

  • Showing the results;

Project Setup

Configuring the Application

I’m using Laravel 5.2 in this tutorial.

Create a new Laravel application with:

or:

Next, install laravelcollective/html. You can do this in the require section in composer.json:

In the terminal:

Go to config/app.php and add the laravelcollective/html to the providers and alias sections.

In the same file, add the two alias:

We will be using SQLite for storing the tasks. Create the database file in database/database.sqlite (assuming you are in the root of the project):

Set the environmental variables in the .env file, located in the root of the project:

You can delete the DB_DATABASE, DB_USERNAME, and DB_PASSWORD variables.

Finally, change the line in config/database.php :

To:

Launch your server and you should be able to see the project running in http://localhost:8000

Controller, Model and Migration

Create the controller:

Now create the task model and migration with the following command:

Let’s add the two columns to the task table. Your migration file should be something like database/migrations/2016_08_23_093058_create_tasks_table.php.

Make the description field fillable in the app/Task.php

Don’t forget to run the migration:

Organizing Folders and Files

There isn’t a default folder for repositories or interfaces, so feel free to create one. I recommend creating a Repositories folder inside app.

Create the Interface

You can create folders to each business logic. For instance, if we had an User, you could place it in app/Repositories/User/UserRepository.php. But that is up to you.

For simplicity, let’s define the interface in app/Repositories/TaskRepository.php.

Here we defined a simple interface with the basics of CRUD operations. Don’t forget to add the namespace on the top.

Implementing the Interface

Write the implementation of the repository in app/Repositories/EloquentTask.php.

The $model variable represents the Task model. He is set through the dependency Task $model in the constructor. Here, we access Eloquent commands from the model.

In the traditional MVC approach we can access the model directly through the controller. In this pattern, the controller only has access to the interface (TaskRepository.php). The implementation EloquentTask.php is the only one to access the Task model directly.

Binding the Interface with Implementation

We need to bind this interface with the correspondent implementation.

In app/Providers/AppServiceProvider.php:

First, we use TaskRepository and EloquentTask on top of the file. Then, in register() we bind the interface with his implementation. This is the same to say that whenever we pass our interface (TaskRepository), assume that we are referring to EloquentTask. We also could say that EloquentTask is the “official” implementation of Task Repository.

Controller Methods

In the TaskController we will be using our interface to interact with the data. Type this code in app/Http/Controller/TaskController.php and follow the explanation in the end.

The first thing you notice is the TaskRepository dependency in the constructor. We assign the interface to a private $task variable, so it can be accessible through our controller.

Remember that we bind the TaskRepository interface with his implementation, Eloquent Task? This allow us to pass an interface directly in the constructor. Now Laravel knows that we are talking about his implementation, Eloquent Task. Thus, TaskController can manipulate the data through an abstraction without touching the model.

Anytime you see $this->task we’re referring to the interface, not the model. Just look at RepositoryTask.php and you will see that we’re calling his methods.

Defining the Routes

Finally, we can set up the routes. Define these in app/Http/routes.php

Showing the Result in a View

I decided to use Bootstrap for styling. Here is the view in resources/views/tasks/index.blade.php:

At last, run your server if you haven’t yet and access http://localhost:8000. Everything should be working fine.

Conclusion

The Repository Pattern is a great way to clean your controller. By using interfaces the controller communicate with the model through an abstraction. Thus, keeping the business logic and presentation separated when dealing with complex data structures. Besides, by separating components, we increase readability, testability and reusability.

There are other topics which can greatly improve what we have done here, like View Composers and custom Requests. These will be treated in future articles.

Share you thoughts in the comment section bellow.

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInShare on Reddit

Published by

Feliciano

Developer with experience in PHP, Laravel, Ruby on Rails, and Android. B.S. in Information Technology.

3 thoughts on “Introduction to Repository Pattern with Laravel 5”

  1. The Repository pattern encapsulates low-level implementation of storing and removing of passed entities:

    interface TaskRepository
    {
    function getAll();
    function getById($id);
    function add(Task $task);
    function save(Task $task);
    function remove(Task $task);
    }

    It cannot contain high-level methods like “create” in the article.

Leave a Reply

Your email address will not be published. Required fields are marked *