The Repository Pattern is very useful in Laravel, it makes it easy to maintain code, and minimizes the logic handling in the Controller. Repository is an abstraction
, that is, it creates a layer between the logic and database processing in the application.
Repository is used to solve the separation when deploying an application, this is very important when writing code that makes it easy to maintain. For example, when our application is using MySQL and wants to change to MongoDB. Because we use the Repository Pattern, all the logic in our application is preserved and all we have to do is change the repository only. It sounds easier then right? ?
Let’s take a look at a simple example to better understand:
Step 1: Create a Repository Interface
We need an interface to act as a contract for the repository . So, what is contract?
Contract is simply like a written contract describing a specific job, here it is the interface .
Create a folder inside the app folder named Repositories .
Then create 1 PostRepositoryInterface.php file .
This is the interface that we will use. Inside this interface , you add the following code:
1 2 3 4 5 6 7 | <span class="token keyword">namespace</span> <span class="token package">App Repositories</span> <span class="token punctuation">;</span> <span class="token keyword">interface</span> <span class="token class-name">PostRepositoryInterface</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> |
Now, we need to add contracts or methods so that PostRepository can implement later:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <span class="token keyword">namespace</span> <span class="token package">App Repositories</span> <span class="token punctuation">;</span> <span class="token keyword">interface</span> <span class="token class-name">PostRepositoryInterface</span> <span class="token punctuation">{</span> <span class="token comment">/** * Get's a post by it's ID * * @param int */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">get</span> <span class="token punctuation">(</span> <span class="token variable">$post_id</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">/** * Get's all posts. * * @return mixed */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">all</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">/** * Deletes a post. * * @param int */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">delete</span> <span class="token punctuation">(</span> <span class="token variable">$post_id</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">/** * Updates a post. * * @param int * @param array */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">update</span> <span class="token punctuation">(</span> <span class="token variable">$post_id</span> <span class="token punctuation">,</span> <span class="token keyword">array</span> <span class="token variable">$post_data</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Note that there will be no closing and opening braces {}, because we do not implement the function in the interface (if you forget you can review the properties in OOP object-oriented programming), so there will be no The logic handling is in the interface, methods are only allowed to be declared.
Step 2: Create a Repository
We start creating the class . Inside the Repositories folder create PostRepository.php file This class will re-implement the PostRepositoryInterface interface that we just created in Step 1 .
The code in the PostRepository.php file is as follows:
1 2 3 4 5 6 7 | <span class="token keyword">namespace</span> <span class="token package">App Repositories</span> <span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">PostRepository</span> <span class="token keyword">implements</span> <span class="token class-name">PostRepositoryInterface</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> |
Next, still in the PostRepository.php file, we are required to create methods declared in the interface and implement them, otherwise there will be errors during the run and will not use the class we have just created.
Here we will use the Eloquent Post model, so we must declare it to use:
1 2 | <span class="token keyword">use</span> <span class="token package">App Post</span> <span class="token punctuation">;</span> |
Edit PostRepository.php as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | <span class="token keyword">namespace</span> <span class="token package">App Repositories</span> <span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">App Post</span> <span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">PostRepository</span> <span class="token keyword">implements</span> <span class="token class-name">PostRepositoryInterface</span> <span class="token punctuation">{</span> <span class="token comment">/** * Get's a post by it's ID * * @param int * @return collection */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">get</span> <span class="token punctuation">(</span> <span class="token variable">$post_id</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Post <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">find</span> <span class="token punctuation">(</span> <span class="token variable">$post_id</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Get's all posts. * * @return mixed */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">all</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Post <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">all</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * Deletes a post. * * @param int */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">delete</span> <span class="token punctuation">(</span> <span class="token variable">$post_id</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> Post <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">destroy</span> <span class="token punctuation">(</span> <span class="token variable">$post_id</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">/** * Updates a post. * * @param int * @param array */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">update</span> <span class="token punctuation">(</span> <span class="token variable">$post_id</span> <span class="token punctuation">,</span> <span class="token keyword">array</span> <span class="token variable">$post_data</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> Post <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">find</span> <span class="token punctuation">(</span> <span class="token variable">$post_id</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">update</span> <span class="token punctuation">(</span> <span class="token variable">$post_data</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Thus, we have created an interface and a class using that interface . Now, we need to register the repository with the container in Laravel
Step 3: Declare Repository with Laravel IoC Container
Create a BackendServiceProvider.php file inside the Repositories folder. This file serves as a connection to the Laravel IoC Container and allows us to use dependency injection to add to our interface repository.
Code in BackendServiceProvider.php
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <span class="token keyword">namespace</span> <span class="token package">App Repositories</span> <span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Illuminate Support ServiceProvider</span> <span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">BackendServiceProvider</span> <span class="token keyword">extends</span> <span class="token class-name">ServiceProvider</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">register</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">app</span> <span class="token operator">></span> <span class="token function">bind</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'AppRepositoriesPostRepositoryInterface'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'AppRepositoriesPostRepository'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
One thing to note here is the order between the interface and the class , you have to put the interface before the class you use, in this example, if you try to put AppRepositoriesPostRepository
before AppRepositoriesPostRepositoryInterface
, you will get an error, You must bind the interface first.
After the above steps, we will have a directory structure and files as follows:
1 2 3 4 5 6 | - app --- Repositories ------ BackendServiceProvider.php ------ PostRepositoryInterface.php ------ PostRepository.php |
Step 4: Use the Repository in the Controller
We start using the repository , assuming we already have a controller
called PostController.php and this controller handles everything related to your Post.
All we have to do is add the interface to the controller through the constructor when the controller is initialized. This way we can use the repository for interactions with posts models :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <span class="token keyword">namespace</span> <span class="token package">App Http Controllers</span> <span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">App Http Requests</span> <span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">App Repositories PostRepositoryInterface</span> <span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">PostController</span> <span class="token keyword">extends</span> <span class="token class-name">Controller</span> <span class="token punctuation">{</span> <span class="token keyword">protected</span> <span class="token variable">$post</span> <span class="token punctuation">;</span> <span class="token comment">/** * PostController constructor. * * @param PostRepositoryInterface $post */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__construct</span> <span class="token punctuation">(</span> PostRepositoryInterface <span class="token variable">$post</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">post</span> <span class="token operator">=</span> <span class="token variable">$post</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * List all posts. * * @return mixed */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">index</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$data</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'posts'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">post</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">all</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token function">view</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'templates.posts'</span> <span class="token punctuation">,</span> <span class="token variable">$data</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
The first we add the PostRepositoryInterface to the constructor
We then set a $ post variable to an instance
of the PostRepository
object through the interface . This allows us to call the PostRepository methods just like we used with the index () method, as you can see:
1 2 3 4 | <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">post</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">update</span> <span class="token punctuation">(</span> <span class="token variable">$data_array</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">post</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">delete</span> <span class="token punctuation">(</span> <span class="token variable">$post_id</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">post</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">get</span> <span class="token punctuation">(</span> <span class="token variable">$post_id</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
This prevents direct access to the model like Post::find($id)
, and it adds us an abstract class into the application.
At the beginning of the article, we mentioned stopping using MySQL and using MongoDB instead, or any other technology, all you need to do is just change the logic of PostRepository.
That means that the code in our controller doesn’t need to be changed.
Step 5: Use more Repository
In an application you can add many different Repository. All you need to do is create an interface and then create a repository , then register them with the Laravel IoC Container in the Service Provider .
For example, we add a ** Comment Repository **
In the app directory:
1 2 3 4 5 6 7 | <span class="token operator">-</span> Repositories <span class="token operator">--</span> <span class="token operator">-</span> BackendServiceProvider <span class="token punctuation">.</span> php <span class="token operator">--</span> <span class="token operator">--</span> <span class="token operator">--</span> PostRepositoryInterface <span class="token punctuation">.</span> php <span class="token operator">--</span> <span class="token operator">--</span> <span class="token operator">--</span> PostRepository <span class="token punctuation">.</span> php <span class="token operator">--</span> <span class="token operator">--</span> <span class="token operator">--</span> CommentRepositoryInterface <span class="token punctuation">.</span> php <span class="token operator">--</span> <span class="token operator">--</span> <span class="token operator">--</span> CommentRepository <span class="token punctuation">.</span> php |
Creating a CommentRepositoryInterface is similar to creating a PostRepositoryInterface in the previous steps.
CommentRepositoryInterface.php
1 2 3 4 5 6 7 8 | <span class="token keyword">namespace</span> <span class="token package">App Repositories</span> <span class="token punctuation">;</span> <span class="token keyword">interface</span> <span class="token class-name">CommentRepositoryInterface</span> <span class="token punctuation">{</span> <span class="token comment">// Define all methods here but remember not to use curly braces.</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">all</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Like this..</span> <span class="token punctuation">}</span> |
CommentRepository.php
1 2 3 4 5 6 7 8 9 10 11 12 13 | <span class="token keyword">namespace</span> <span class="token package">App Repositories</span> <span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">App Comment</span> <span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">CommentRepository</span> <span class="token keyword">implements</span> <span class="token class-name">CommentRepositoryInterface</span> <span class="token punctuation">{</span> <span class="token comment">// Must use all methods that were defined in the CommentRepositoryInterface here</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">all</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Comment <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">all</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Finally, declare it in the IoC Container inside BackendServiceProvider.php .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <span class="token keyword">namespace</span> <span class="token package">App Repositories</span> <span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Illuminate Support ServiceProvider</span> <span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">BackendServiceProvider</span> <span class="token keyword">extends</span> <span class="token class-name">ServiceProvider</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">register</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">app</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">bind</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'AppRepositoriesPostRepositoryInterface'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'AppRepositoriesPostRepository'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">app</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">bind</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'AppRepositoriesCommentRepositoryInterface'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'AppRepositoriesCommentRepository'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Above is my find out about Repository in Laravel. Hope it can help you!