Skip to main content

Service: Most Misunderstood Word in Laravel?

Premium
5 min read

The word "service" is often used in the Laravel community, but is it a "design pattern"?

Yes and no.

It is a pattern in the sense that it's a typical approach to offload the logic from the Controller to "somewhere else", that "somewhere" being the Service class.

However, identically to the Action classes, Services are not a core Laravel function, so there's no php artisan make:service, and developers can name/structure them however they want.

I've seen two main use cases for Service classes:

Case 1. Something like UserService: A class with multiple methods around a certain Model or other subject (more "loose" pattern)

Case 2. Something like StripeService: A class that helps to work with external functionality or a 3rd party library that can be replaced with another library in the future (more "strict" pattern)

And let's see both in action.


"Loose" Services Example

A typical simple example is this:

app/Http/Controllers/UserController.php:

use App\Http\Requests\StoreUserRequest;
use App\Services\UserService;
 
class UserController extends Controller
{
public function store(StoreUserRequest $request, UserService $userService)
{
$userService->store($request->validated());
 
return redirect()->route('users.index');
}
 
// ...
}

Then, inside that UserService class, you have methods to store users, update users, and perform other operations related to the User model.

app/Services/UserService.php:

namespace App\Services;
 
class UserService {
 
public function store(array $userData): User
{
$user = User::create($userData);
 
$user->roles()->sync($userData['roles']);
 
// More actions with that user: let's say, 5+ more lines of code
// - Upload avatar
// - Email to the user
// - Notify admins about new user
// - Create some data for that user
// - and more...
 
return $user;
}
 
public function update(array $userData, User $user): User
{
$user->update($userData);
$user->roles()->sync($userData['roles']);
 
// Also, more actions with that user
}
}

Wait, How Does That "Magic" Type-Hinting Work?

So, you've seen this code...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (36 h 00 min)

You also get:

61 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

angel avatar

The type-hint of Service class inside of another Service class works well. The Service container also take care of that.

And you can also resolve a service from the container inside an other service if you don't use type-hint without the need of of explicit usage of new keyword :

use app\Services\TwitterService;
 
class UserService {
 
public function store(array $userData, TwitterService $twitter): User
{
$twitter->tweet()
}
}
use app\Services\TwitterService;
 
class UserService {
 
public function __construct(private readonly TwitterService $twitter){}
 
public function store(array $userData): User
{
$twitter->tweet()
}
}
use app\Services\TwitterService;
 
class UserService {
public function store(array $userData): User
{
$twitter= app(UserService::class);
$twitter->tweet()
}
}

You can read more here : https://laravel.com/docs/11.x/container#resolving

👍 4

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.