Services
Les Services contiennent la logique métier qui n'appartient ni aux contrôleurs, ni aux modèles, ni aux vues.
Responsabilités
| Un service peut | Un service ne doit pas |
|---|---|
| Coordonner des workflows | Rendre des vues Blade |
| Utiliser des repositories et modèles | Lire des données de requête HTTP brutes |
| Ouvrir des transactions | Vérifier des détails de formulaire HTML |
| Émettre des événements | Masquer les décisions d'autorisation aux contrôleurs |
| Écrire des logs d'audit | Dupliquer les accesseurs de modèle |
Exemples de cas d'usage
- Synchronisation (Proxmox, données externes)
- Imports et exports
- Calculs métier
- Génération d'alertes
- Workflows de validation
- Génération de contenu IA
- Calculs d'occupation (Élevage)
Pattern — logique sensible
public function updateSettings(Application $application, array $data): Application
{
try {
return DB::transaction(function () use ($application, $data): Application {
$application->fill($data);
$application->save();
Log::info('Application settings updated', [
'id_application' => $application->id_application,
]);
return $application;
});
} catch (Throwable $exception) {
Log::error('Application settings update failed', [
'id_application' => $application->id_application,
'error' => $exception->getMessage(),
]);
throw $exception;
}
}
:::warning Règle obligatoire
Utiliser try/catch autour des workflows sensibles : imports, exports, changements de permissions, paramètres, appels externes.
:::
Injection de dépendances
final class UserService
{
public function __construct(
private readonly UserRepository $users,
private readonly AuditLogger $audit,
) {}
public function assignRole(User $user, Role $role): void
{
$this->authorize('assignRole', $user);
DB::transaction(function () use ($user, $role): void {
$user->roles()->sync($role->id_role);
$this->audit->log('user.role_assigned', $user, ['role' => $role->code]);
});
}
}
Provider IA (AiProviderConfigService)
Les modules utilisant l'IA doivent passer par AiProviderConfigService, jamais hardcoder les URLs ou clés.
use Modules\Ai\Services\AiProviderConfigService;
$config = app(AiProviderConfigService::class)->textProvider('my_feature');
// Retourne : code, base_url, api_key, model, timeout
$config = app(AiProviderConfigService::class)->imageProvider();