How to Use Repository Pattern in Laravel Effectively ?

Link Copied To Clipboard !

repository=pattern-in-laravel Frameworks

Repository pattern in programming is a concept used to separate data access layer from business logic layer of an application. It decouples and centralizes the data source functionalities like any database operations into a separate abstraction layer.

Repository pattern can be used in any programming language or framework as long as it uses data source technologies to store and manipulate data. It is widely used in an application framework that uses MVC paradigm for application development because it helps to decouple database related codes from other views and controller logic.

How is repository pattern implemented ?

To use the concept of repository pattern, we make use of interfaces. An interface provides the abstraction to all functions a repository is supposed to have. Then, a repository class is made to implement that interface so that it implements all abstract functions defined in interface.

Next time when we need to access database for a model, we simple use that repository class to reference required data source functions. This way, all database operations are separated from business logic and controllers and put into a separate package so that the future modifications and maintenance will be so much easier.

Why should we use repository pattern ?

Repository pattern helps to decouple business logic from database operations. If you are building a large application, then you will surely have lots of lines of codes in your controller. If you put your database codes also in controller functions, imagine how many lines of codes you will have in a single file. If you use repository pattern, you will separate codes that are related to database into a repository package and your business logic into separate package.

Another scenario a repository pattern helps overcome is when you need to change your data source engine. Let’s consider you have used MySQL database as a data source for now. Imagine you have used repository pattern. Suppose after a year, you decide to change your data source into firebase. Now, if you hadn’t used repository pattern, you will have to completely rewrite your code to make it compatible with firebase. That would be a real disaster right ? But, let’s say you used repository pattern before. Now when you need to change data source engine, you only have to modify repository class ,not even an interface because we want all those functions. Only changes on repository function implementations; only implementations not even function names.

How to use repository pattern in laravel ?

In laravel, you will have routes, controllers, models and views. Laravel has an ORM tool called Eloquent to facilitate database operations. Traditionally, we could write all controller functions and database codes in a controller itself. But, since we are trying to implement repository pattern, let’s see how it’s done.

Suppose we have a route /products for a model Product.php. Let’s say we have a controller ProductsController.php for handling /products/ routes. Now, to implement repository pattern, we have to first create an interface, let’s call it ProductsInterface.php and put it inside Interfaces directory. The ProductsInterface.php will look something like this:

interface ProductsInterface{
   	public function all(): LengthAwarePaginator;
        public function find($id): ProductsRepository;
        public function create(array $data = []): Product;
}

We have created only three functions but you have to create as required by your application functionalities. Now, we need to create a repository class that implements this interface. Let’s create ProductsRepository.php and put it inside Repositories directory. This class will implement all functions defined in ProductsInterface.php and look something like:

class ProductsRepository implements ProductsInterface{

   	private Product $product;

        public function __construct(Product $product){
        	$this->product = $product;
        }
        
        public function all(): LengthAwarePaginator{
        	return $this->product->paginate();
        }
        
        public function find($id): ProductRepository{
        	$this->product = $this->product::findOrFail($id);
            return $this;
        }
        
        public function create(array $data = []): Product{
        	return $this->product->store($data);
        }
}

At this point, we have successfully created our repository class for Product.php model. Let’s see how we can use it in our controller class ProductsController.php .

class ProductsController{

   	private ProductsRepository $repository;
        
        public function __construct(ProductsRepository $repository){
        	$this->repository = $repository;
        }
        
        public function all(): LengthAwarePaginator{
        	return $this->repository->all();
        }
        
        public function save(Request $request): Product{
        	return $this->repository->create($request->all());
        }
}

As you can see, we first inject our repository into the constructor and later use it whenever we need to access database.

Naming convention for repository class

Usually, when we create functions, we name it as it becomes easier to understand. For example, if we were to create a function that returns all products, we would name it getAllProducts() . The question is, is this convention good in repository class ? Not really. Let me explain why. When we create a repository class, we name it using the model name. For example, For model Product.php the repository class will be ProductsRepository.php . So, anything we write inside this class will most certainly be related to Product model right ?

That is why, we will remove the word product from all function definitions inside ProductsRepository.php . You can imagine now what the function names will be. To get all products, may use all(), to find a product using id, we may write a function find($id) and so on.

Hope you get the idea now.

HAPPY CODING !


You May Also Like