1. Accueil
  2. Articles
2 min de lecture
12 vues

Action vs Service dans Laravel : où placer sa logique métier ?

Image d'illustration pour Action vs Service dans Laravel : où placer sa logique métier ?

#Action vs Service dans Laravel

Service pour les capacités réutilisables. Action pour les opérations métier précises.

Quand un Controller commence à contenir trop de logique métier, il est temps de l'extraire.

Deux approches sont particulièrement courantes dans Laravel :

  • Service
  • Action

Mais lequel choisir ?

#Le Service

Un Service regroupe généralement plusieurs opérations liées au même domaine.

1class PaymentService
2{
3 public function charge(Order $order)
4 {
5 // ...
6 }
7 
8 public function refund(Order $order)
9 {
10 // ...
11 }
12 
13 public function verify(Order $order)
14 {
15 // ...
16 }
17}
1class PaymentService
2{
3 public function charge(Order $order)
4 {
5 // ...
6 }
7 
8 public function refund(Order $order)
9 {
10 // ...
11 }
12 
13 public function verify(Order $order)
14 {
15 // ...
16 }
17}

Ici, on regroupe plusieurs capacités liées au paiement :

1PaymentService
2├── charge()
3├── refund()
4└── verify()
1PaymentService
2├── charge()
3├── refund()
4└── verify()

C'est particulièrement utile lorsque ces fonctionnalités doivent être réutilisées à plusieurs endroits.


#L'Action

Une Action représente une opération métier précise.

1class CreateOrderAction
2{
3 public function execute(array $data): Order
4 {
5 // ...
6 }
7}
1class CreateOrderAction
2{
3 public function execute(array $data): Order
4 {
5 // ...
6 }
7}

Au lieu d'avoir un énorme OrderService :

1OrderService
2├── create()
3├── update()
4├── cancel()
5├── refund()
6└── ...
1OrderService
2├── create()
3├── update()
4├── cancel()
5├── refund()
6└── ...

On peut séparer les opérations :

1CreateOrderAction
2UpdateOrderAction
3CancelOrderAction
4RefundOrderAction
1CreateOrderAction
2UpdateOrderAction
3CancelOrderAction
4RefundOrderAction

Chaque classe a ainsi une responsabilité clairement définie.


#La différence

La question à se poser est simple :

Est-ce une capacité ou une opération ?

#Capacité → Service

1PaymentService
2EmailService
3FileStorageService
1PaymentService
2EmailService
3FileStorageService

#Opération métier → Action

1CreateOrderAction
2ApproveInvoiceAction
3CancelSubscriptionAction
1CreateOrderAction
2ApproveInvoiceAction
3CancelSubscriptionAction

#Pourquoi pas utiliser les deux ?

Les deux patterns peuvent parfaitement fonctionner ensemble.

Par exemple :

1OrderController
2
3CreateOrderAction
4
5 ┌───────────────┐
6 ↓ ↓
7PaymentService InventoryService
1OrderController
2
3CreateOrderAction
4
5 ┌───────────────┐
6 ↓ ↓
7PaymentService InventoryService

L'Action orchestre le cas d'utilisation.

Les Services fournissent les capacités nécessaires.


#En résumé

Service Action
Regroupe des capacités Représente une opération
Plusieurs méthodes Généralement une méthode
PaymentService CreateOrderAction
Orienté capacité / domaine Orienté cas d'utilisation

Il n'y a donc pas de pattern universellement meilleur.

Service pour les capacités réutilisables. Action pour les opérations métier précises.

Et dans une application complexe, les deux peuvent parfaitement cohabiter.