Techy StatusTechy Status

    Subscribe to Updates

    Get the latest creative news from FooBar about art, design and business.

    What's Hot

    Redis, Kafka or RabbitMQ

    March 22, 2023

    Find User ID from Laravel Passport Token

    June 18, 2022

    Apple Could Add a Camera to Future Apple Watch

    June 5, 2022
    Facebook Twitter Instagram
    Facebook Twitter Instagram
    Techy Status Techy Status
    • Home
    • News
    • Smart Tech
    • Development
    Techy StatusTechy Status
    Home » All Articles » Repository Pattern in a Laravel Application
    Development

    Repository Pattern in a Laravel Application

    techybibiBy techybibiMay 14, 2022No Comments5 Mins Read
    Share
    Facebook Twitter LinkedIn Pinterest Email Reddit WhatsApp

    A repository can be defined as a layer of abstraction between the domain and data mapping layers, one that provides an avenue of mediation between both, via a collection-like interface for accessing domain objects.

    A key benefit of the Repository pattern is that it allows us to use the Principle of Dependency Inversion (or code to abstractions, not concretions). This makes our code more robust to changes, such as if a decision was made later on to switch to a data source that isn’t supported by Eloquent.

    It also helps with keeping the code organized and avoiding duplication, as database-related logic is kept in one place. While this benefit is not immediately apparent in small projects, it becomes more observable in large-scale projects which have to be maintained for many years.

    In this article, I will show you how to implement the Repository pattern in your Laravel applications.

    Create the Repository

    Before we create a repository for the Order model, let’s define an interface to specify all the methods which the repository must declare. Instead of relying directly on the repository class, our controller (and any order component we may build in the future) will depend on the interface.

    This makes our code flexible because, should it become necessary to make a change in the future, the controller remains unaffected. For instance, if we decided to outsource order management to a 3rd party application, we can build a new module that conforms to OrderRepositoryInterface‘s signature and swap the binding declarations and our controller will work exactly as expected – without touching a single line of code in the controller.

    In the app directory, create a new folder called Interfaces. Then, in the Interfaces, create a new file called OrderRepositoryInterface.php and add the following code to it.

    <?php
    
    namespace App\Interfaces;
    
    interface OrderRepositoryInterface 
    {
        public function getAllOrders();
        public function getOrderById($orderId);
        public function deleteOrder($orderId);
        public function createOrder(array $orderDetails);
        public function updateOrder($orderId, array $newDetails);
        public function getFulfilledOrders();
    }

    Next, in the app folder, create a new folder called Repositories. In this folder, create a new file called OrderRepository.php and add the following code to it.

    <?php
    
    namespace App\Repositories;
    
    use App\Interfaces\OrderRepositoryInterface;
    use App\Models\Order;
    
    class OrderRepository implements OrderRepositoryInterface 
    {
        public function getAllOrders() 
        {
            return Order::all();
        }
    
        public function getOrderById($orderId) 
        {
            return Order::findOrFail($orderId);
        }
    
        public function deleteOrder($orderId) 
        {
            Order::destroy($orderId);
        }
    
        public function createOrder(array $orderDetails) 
        {
            return Order::create($orderDetails);
        }
    
        public function updateOrder($orderId, array $newDetails) 
        {
            return Order::whereId($orderId)->update($newDetails);
        }
    
        public function getFulfilledOrders() 
        {
            return Order::where('is_fulfilled', true);
        }
    }
    

    Apart from the flexibility provided by the interface, encapsulating queries in this manner has the added advantage that we don’t have to duplicate queries throughout the application.

    If, in the future, we decide to retrieve only unfulfilled orders in the getAllOrders() function, we would only have to make a change in one place instead of tracking down all the places where Order::all() is declared while risking missing some.

    Creating the controllers

    With our repository in place, let’s add some code to our controller. Open app/Http/Controllers/OrderController.php and update the code to match the following.

    <?php
    
    namespace App\Http\Controllers;
    
    use App\Interfaces\OrderRepositoryInterface;
    use Illuminate\Http\JsonResponse;
    use Illuminate\Http\Request;
    use Illuminate\Http\Response;
    
    class OrderController extends Controller 
    {
        private OrderRepositoryInterface $orderRepository;
    
        public function __construct(OrderRepositoryInterface $orderRepository) 
        {
            $this->orderRepository = $orderRepository;
        }
    
        public function index(): JsonResponse 
        {
            return response()->json([
                'data' => $this->orderRepository->getAllOrders()
            ]);
        }
    
        public function store(Request $request): JsonResponse 
        {
            $orderDetails = $request->only([
                'client',
                'details'
            ]);
    
            return response()->json(
                [
                    'data' => $this->orderRepository->createOrder($orderDetails)
                ],
                Response::HTTP_CREATED
            );
        }
    
        public function show(Request $request): JsonResponse 
        {
            $orderId = $request->route('id');
    
            return response()->json([
                'data' => $this->orderRepository->getOrderById($orderId)
            ]);
        }
    
        public function update(Request $request): JsonResponse 
        {
            $orderId = $request->route('id');
            $orderDetails = $request->only([
                'client',
                'details'
            ]);
    
            return response()->json([
                'data' => $this->orderRepository->updateOrder($orderId, $orderDetails)
            ]);
        }
    
        public function destroy(Request $request): JsonResponse 
        {
            $orderId = $request->route('id');
            $this->orderRepository->deleteOrder($orderId);
    
            return response()->json(null, Response::HTTP_NO_CONTENT);
        }
    }

    The code injects an OrderRepositoryInterface instance via the constructor and uses the relevant object’s methods in each controller method.

    First, within the index() method, it calls the getAllOrders() method defined in the orderRepository to retrieve the list of orders and returns a response in JSON format.

    Next, the store() method calls the createOrder() method from the orderRepository to create a new order. This takes the details of the order that needs to be created as an array and returns a successful response afterward.

    Within the show() method in the controller, it retrieves the unique order Id from the route and passes it to the getOrderById() as a parameter. This fetches the details of the order with a matching Id from the database and returns a response in JSON format.

    Then, to update the details of an already created order, it calls the updateOrder() method from the repository. This takes two parameters: the unique id of the order and the details that need to be updated.

    Lastly, the destroy() method retrieves the unique id of a particular order from the route and calls the deleteOrder() method from the repository to delete it.

    Adding the routes

    To map each method defined in the controller to specific routes, add the following code to routes.

    Route::get('orders', [OrderController::class, 'index']);
    Route::get('orders/{id}', [OrderController::class, 'show']);
    Route::post('orders', [OrderController::class, 'store']);
    Route::put('orders/{id}', [OrderController::class, 'update']);
    Route::delete('orders/{id}', [OrderController::class, 'delete']);

    Remember to include the import statement for the OrderController.

    use App\Http\Controllers\OrderController;

    That’s how to use the Repository Pattern in a Laravel application

    In this article, we learned about the Repository pattern and how to use it in a Laravel application. We’ve also seen some of the benefits it offers for a large-scale project – one of which is loosely coupled code where we are coding to abstractions, not concrete implementations.

    laravel repository
    Share. Facebook Twitter Pinterest LinkedIn Tumblr Email Reddit WhatsApp
    Previous ArticleVodafone Idea (Vi) Introduces Rs 195 and Rs 319 Recharge Plans with 31 Days of Validity
    Next Article Laravel Socialite Login with Facebook Tutorial

    Related Posts

    Redis, Kafka or RabbitMQ

    March 22, 2023

    Find User ID from Laravel Passport Token

    June 18, 2022

    Laravel Socialite Login with Facebook Tutorial

    May 24, 2022
    Add A Comment

    Leave A Reply Cancel Reply

    Editors Picks

    Redis, Kafka or RabbitMQ

    March 22, 2023

    Find User ID from Laravel Passport Token

    June 18, 2022

    Apple Could Add a Camera to Future Apple Watch

    June 5, 2022

    Vodafone Idea (Vi) Introduces Rs 195 and Rs 319 Recharge Plans with 31 Days of Validity

    May 1, 2022
    Top Reviews
    Advertisement
    Techy Status
    Facebook Twitter Instagram YouTube
    © 2023 TechyStatus.com. Managed by Talkbate Digital Partners.

    Type above and press Enter to search. Press Esc to cancel.