Repository Pattern In Laravel Sometimes Makes You “Over Engineering”

Agun Buhori
3 min readJun 3, 2024

--

One of the best architectures in Laravel is using a repository pattern, which means we separate our business logic into separate files called repositories. I differ two types of developers who use it as their choice, firstly are “perfectionist developers” and secondly are “YAGNI developers” (you ain’t gonna need it). Indeed, sometimes it is necessary to break code into several files to make the code we create easy to read and scale, but it will become over-files and over-engineering if we use it excessively. For example, to overwrite functions that Laravel itself has made easy for us to use it, like Eloquent.

Here is an example of the implementation of the Laravel Repository pattern, that makes the developer look “over-engineering.”

Firstly, the developer writes the repository class to override the existing methods in Laravel:

<?php

use App\Models\User;

class UserRepository
{
public function getAll()
{
return User::all();
}

public function getById($id)
{
return User::find($id);
}

public function store($data)
{
return User::create($data);
}

// I think you know the rest
}

Secondly, the developer calls it in their controller like this:

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Closure;
use Illuminate\Contracts\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Pipeline;
use UserRepository;

class UserController extends Controller
{
public UserRepository $userRepository;

public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}

public function index()
{

return $this->userRepository->getAll();
}

public function show($id)
{

return $this->userRepository->getById($id);
}


public function store(Request $request)
{

return $this->userRepository->store($request->all());
}

// You know the rest

}

Laravel Makes You Easy, You Make It Harder

If you only display data with a query that only needs to be written in one or two lines, using a repository is just rubbish and a waste of your time, and you don’t appreciate the Laravel developers who have made it easy for you. This coding style may be popular with perfectionist developers, but it only makes it a lot of hassle for developers to move files around more often for simple tasks. You need to know, Eloquent is the repository itself, meaning it connects you to the database from the controller.

Writing code like this and still taking advantage of Laravel’s built-in features is not bad, in fact, it is easier to read than having to overwrite some of the functions that are already provided. Unless we really want to separate logic that is quite complex and will use up a lot of lines, then it might be appropriate to separate it into a particular repository so that the code looks cleaner. You may argue that consistency and uniformity are very important, but again, if applied as a whole, this will make your project increasingly bloated and difficult to manage.

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Closure;
use Illuminate\Contracts\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Pipeline;
use UserRepository;

class UserController extends Controller
{
public UserRepository $userRepository;

public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}

public function index()
{
return User::all();
}

public function show($id)
{

return User::find($id);
}


public function store(Request $request)
{

return $this->userRepository->expensiveStoreFunction($request->all());
}
}

Wasteful Test Writing

You might also argue that creating a repository and overriding some of the default functions in Laravel also makes it easier for you to test it. But remember, you can create better test scenarios without having to create a repository that only contains simple commands to override existing methods.

--

--