skip to Main Content

I am implementing the Repository Pattern (service) in a Laravel application and I have some doubts about the usage of interfaces with these services.

I have created an interface called CRUD (code bellow) to serve as a way to always keep the same names for the services that are going to implement CRUD methods.

<?php

namespace AppInterfaces;

interface CRUD
{
  public function create(array $data);
  public function update(int $id, array $data);
  public function delete(string $ids);
};

Bellow there’s an example of how I call my service and the service itself, and that’s where my doubts are. Usually I’ll see people witing an interface for each service and demanding the controller to have injected an objet of that type. Because of that, people will have to bind a specific type (interface) to the controller. It seems redundant and thus I simply passed the service I need.

Now, is this ok or I should pass the CRUD interface to the controller in this case? Or should I even create another interface specifically for each service?

<?php

namespace AppHttpControllersCms;

use AppHttpControllersController;
use AppHttpRequestsGroupRequest;
use AppModelsGroup;
use AppServicesGroupsService;
use IlluminateHttpRequest;

class GroupsController extends Controller
{
  private $service;

  public function __construct(GroupsService $service)
  {
    $this->service = $service;
  }

  public function store(GroupRequest $request)
  {
    $result = $this->service->create($request->all());
    return redirect()->back()->with('response', $result);
  }

  public function update(GroupRequest $request, $id)
  {
    $result = $this->service->update($id, $request->all());
    return redirect()->back()->with('response', $result);
  }

  public function destroy($groups_id)
  {
    $result = $this->service->delete($groups_id);
    return redirect()->back()->with('response', $result);
  }
}
<?php

namespace AppServices;

use AppModelsGroup;
use AppInterfacesCRUD;
use Exception;

class GroupsService implements CRUD
{
  public function listAll()
  {
    return Group::all();
  }

  public function create(array $data)
  {
    $modules_id = array_pop($data);

    $group = Group::create($data);
    $group->modules()->attach($modules_id);

    return cms_response(trans('cms.groups.success_create'));
  }

  public function update(int $id, array $data)
  {
    try {
      $modules_ids = $data['modules'];
      unset($data['modules']);
      $group = $this->__findOrFail($id);

      $group->update($data);
      $group->modules()->sync($modules_ids);

      return cms_response(trans('cms.groups.success_update'));
    } catch (Throwable $th) {
      return cms_response($th->getMessage(), false, 400);
    }
  }


  public function delete(string $ids)
  {
    Group::whereIn('id', json_decode($ids))->delete();
    return cms_response(trans('cms.groups.success_delete'));
  }

  private function __findOrFail(int $id)
  {
    $group = Group::find($id);
    if ($group instanceof Group) {
      return $group;
    }
    throw new Exception(trans('cms.groups.error_not_found'));
  }
}

2

Answers


  1. If you want to use Repository Design Patteren You have to create seprate Interface for each service accroing to SOLID Principle. You have to create custom service provider and register your interface and service class and then inject interface in construtor of controller.
    You can also follow below article.
    https://itnext.io/repository-design-pattern-done-right-in-laravel-d177b5fa75d4

    Login or Signup to reply.
  2. I did something with repo pattern in laravel 8 you might be interested:

    thats how i did it:

    first of all, you need to implement a provider

    in this file i created the binding:

    AppProvidersRepositoryServiceProvider.php
    
    use AppInterfacesEventStreamRepositoryInterface;
    use AppRepositoriesEventStreamRepository;
    use IlluminateSupportServiceProvider;
    class RepositoryServiceProvider extends ServiceProvider
    {
    
     public function register()
        {
            $this->app->bind(EventStreamRepositoryInterface::class, EventStreamRepository::class);
        }
    
    }
    

    then in file:

    appInterfacesEventStreamRepositoryInterface.php
    
    interface EventStreamRepositoryInterface {
        public function index();
        public function create( Request $request );
        public function delete($id);
    }
    

    in file:

    AppRepositoriesEventStreamRepository.php

    class EventStreamRepository implements EventStreamRepositoryInterface{
    
    public function index()
    {
      return EventStream::with(['sessions'])
            ->where([ ["status", "=", 1] ] )
            ->orderBy('created_at', 'DESC')
            ->get();
    }
    
    
    public function create(Request $request)
    {
        request()->validate([
            "data1"      => "required",
            "data2"      => "required"
        ]);
    
        $EventStream = EventStream::create([
            'data1'      => request("data1"),
            'data2'      => request('data2')
        ]);
    
        return $EventStream->id;
    }
    
    public function delete($id)
    {
      return EventStream::where('id', $id)->delete();
    }
    
    }
    

    in file:

    AppHttpControllersEventStreamController.php

    use AppInterfacesEventStreamRepositoryInterface;
    class EventStreamController extends Controller{
    
    private EventStreamRepositoryInterface $eventStreamRepository;
    
    public function __construct(EventStreamRepositoryInterface $eventStreamRepository)
    {
        $this->eventStreamRepository = $eventStreamRepository;
    }
    
     public function index():JsonResponse
    {
      $this->eventStreamRepository->index();
    }
    
    
        public function store(Request $request ):JsonResponse
        {
         $this->eventStreamRepository->create($request);
        }
    
     public function destroy($id):JsonResponse
        {
            $this->eventStreamRepository->delete($id);   
        }
    
    }//class
    

    note: i think i removed all unnecessary -validations- and -returns- in controller for better reading.

    Hope it helps!!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search