My Laravel project starts to grow up and I'm starting to dealing with fat Controllers and Models. Probably I'm for away from the SOLID principles path and my code is not DRY.
I decided to refactor my layers logic to follow more SOLID and try to be more DRY. After some research over the internet I ended up with the following conclusion:
Let me explain this diagram:
- First, we start with a view, where the user performs some action and the request is sent to the Controller.
- Controller responsibility is to handle the request and give the response to the user. It will be able to call 3 different layers (blue numbers):
- Service: to handle business logic like calculations, special actions, etc.
- Repository: where all query logic will be placed. For example, if on index method we want to return the users list with users that have more than 100 posts and are ordered by name (Example 1).
- Laravel Resource (Transformers): with the responsibility to transform a model into JSON. When we change our table we don't have to change all the views and controllers or models affected by that change. It will be all done in one place.
Example 1:
# UserController.php
public function index()
{
$users = new UserCollection($this->UserRep->usersWithPost());
return view('user-list', compact('users'));
}
# UserRepository.php
public function usersWithPost($min = 100)
{
return $this->model->where('post_count', '>=', $min)->orderBy('name');
}
# UserResource.php
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'post_count' => $this->post_count,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
- Service calls (green numbers):
- It may call Repository if it needs any data from my model to perform some action.
- It also may call Laravel Resource "Transformers" if there were repository calls.
- The repository will use the eloquent model to persist query on my data storage (MySQL).
This is how I plan to refactor my code, however, I do not have experience with Laravel and I would like to ask more experienced developers if they can indicate me if I'm on the right path.
Do you think it makes sense and it is a good practice?
I would like to highlight that I will not switch between ORMs. I will use eloquent with MySQL as my data storage, that's why I'm planning to put all my queries to repositories to have a different layer for queries logic.