Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

joerucci's avatar

Service Class logic and pattern best practices.

Currently I tend to follow a Controller, Service, Model pattern in my projects.

Controller Nothing special here, just the standard Laravel controller class existing at a one to one ratio with my Models.

Service Layer A service layer existing again at a one to one ratio with my Models, all of which extend a generic service class that does simple CRUD operations.

Model Standard Laravel Eloquent model class including relationships.

Generally speaking this is organized and predictable enough but has lend to some confusion in certain relationship situations. For example, Let's say you have a "Team" object which is made up of "User" objects.

Does it make more sense to call the "User" service with...

$userService->users($teamId);
$userService->getById($userId);
$userService->create($teamId, $attributes);

or call the "Team" service class with...

$teamService($teamId)->users();
$teamService($teamId)->getUserById($userId);
$teamService($teamId)->createUser($attributes);

Putting all that logic under the “Team” service seems easier to read/understand but the downside is that you end up with a really fat service class, especially if the “Team” object owns lots of different objects (statuses, tags, comments, posts, etc).

Should I have a combination? For example…

$teamService($teamId)->users();

Actually calls something like this…

public function users()
{
    $userService = new UserService();
    $users = $userService->find(‘team_id’, ‘=‘, $this->$team->id);
    return $users;
}

The same could be asked for the Controllers really. Would love to get some feedback from others that use a similar pattern.

0 likes
2 replies
Robstar's avatar

If your service is just crud/database operations, it's more of a repository than a service.

In your controller you'd see descriptive methods like:

public function users(UserRepo $repo)
{
   // $team is fetched elsewhere ...
   return $repo->findByTeamId($team);
}

However, you need to be careful as it's easy for your Repository to turn into an unnecessary wrapper for Eloquent - which your Service above pretty much is.

joerucci's avatar

Well I do extend my services classes to do more then just CRUD operations usually.

I use to include a repository a while back but have since stopped because of the additional overhead (and I ultimatley don't expect to ever be completely rid of the Eloquent models).

As I have it now, I inject a primary service class into every Controller and every service class has a primary a Model (Eloquent).

It's really just a way for me to keep the Controllers and Models lightweight.

But regardless if I call them repos or service classes, you don't see any issues with a service class calling another service class? Or Repo calling another repo?

Please or to participate in this conversation.