Attention: if you haven’t already seen the first part of this post, please take a look at it. Repository Pattern on Laravel (Part 1).

In the previous post about repositories I talked about how to create an abstraction layer between the controller and the database. We used the following examples: app/Http/Controllers/PostsController.php and app/Repositories/PostRepository.php - to see the codes, just click the link in the top of this post.

I showed how to inject the PostRepository class - the one responsible for making the calls to our model - in our PostsController . That helped us have more control about our queries, etc. However, it doesn’t give us, for instance, flexibility when changing ORMs. To do that, we need to implement an Interface — something that works as a contract to the Class . It basically tells the class which methods it should implement without defining how those methods should be treated, click here to learn more —, then, we need to make Laravel know which class to use whenever this Interface is implemented and then we simply need to inject it in the controller . This way, we can make modifications without having to change anything in the controller. To do that, let’s first create our Interface. You may put your file wherever you want, I’ll put it on `app/Repositories/Contracts’.

<?php // app/Repositories/Contracts/PostRepositoryInterface.php namespace App\Repositories\Contacts ; interface PostRepositoryInterface { public function find (); public function findBy ( $att , $column ); } ?>

Fairly simple: we are simply telling what methods any class that implements PostRepositoryInterface shall have - it needs to have these methods, or it’ll throw an exception.

Now, we need to implement this interface in our PostRepository . Our old code was something like this:

<?php // app/Repositories/PostRepository.php namespace App\Repositories ; use App\Post ; class PostRepository { protected $post ; public function __construct ( Post $post ) { $this -> post = $post ; } public function find ( $id ) { return $this -> post -> find ( $id ); } public function findBy ( $att , $column ) { return $this -> post -> where ( $att , $column ) } } ?>

To implement our PostRepositoryInterface , we simply need to use the operator implements in the class declaration. We also have to import the Interface. It should look like this:

<?php // app/Repositories/PostRepository.php namespace App\Repositories ; use App\Repositories\Contracts\PostRepositoryInterface ; use App\Post ; class PostRepository implements PostRepositoryInterface { protected $post ; public function __construct ( Post $post ) { $this -> post = $post ; } public function find ( $id ) { return $this -> post -> find ( $id ); } public function findBy ( $att , $column ) { return $this -> post -> where ( $att , $column ) } } ?>

Very simple! Now, If you’d want, you could create another repository — using Doctrine, perhaps — and call it, I don’t know, PostRepositoryDoctrine and we’ll have also too implement our interface. This way, we would have two (or more) classes (repositories) that implement the same PostRepositoryInterface . But how is our controller going to know which class (repository) it should inject? Simple: it doesn’t know. Instead of injecting our repository directly in our controller constructor, we’re going to inject our PostRepositoryInterface and then we’ll use Laravel’s Service Container to decide which repository (class) use — or, even better, make the binding between the interface and the class that should be used. So, first, let’s set this up. To do that, open the file app/Providers/AppServiceProvider.php . In the register method, we’re going to bind our interface to our correct repository using the bind method. Kinda like this:

<?php namespace App\Providers ; use Illuminate\Support\ServiceProvider ; class AppServiceProvider extends ServiceProvider { /** * Bootstrap any application services. * * @return void */ public function boot () { // } /** * Register any application services. * * @return void */ public function register () { $this -> app -> bind ( 'App\Repositories\Contracts\PostRepositoryInterface' , 'App\Repositories\PostRepository' ); } } ?>

We basically told Laravel that, whenever a class needs the PostRepositoryInterface interface, it should inject the PostRepository class. Obviously, we also wrote the namespace of each class.

Now, back to our PostController — we’re going to put our PostRepositoryInterface in our class constructor and then Laravel will “decide” (just as we configured in AppServiceProvider ) which class to inject, in our case, PostRepository .

<?php // app/Http/Controllers/PostsController.php namespace App\Http\Controllers ; // antigamente: use App\Repositories\PostRepository; agora não precisamos mais disso pois já definimos qual classe injetar quando necessitarmos da interface PostRepositoryInterface. Iremos importá-la e colocá-la no construtor - repare nas linhas 8 e 13 use App\Repositories\Contracts\PostRepositoryInterface ; class PostsController { protected $post ; public function __construct ( PostRepositoryInterface $post ) { $this -> post = $post ; } public function show ( $slug ) { return $this -> post -> findBy ( 'slug' , $slug ); } } ?>