Aller au contenu

Développeur Laravel senior : APIs de production, multi-tenant et temps réel

Comment je construis des backends Laravel qui font tourner une activité : une couche service derrière des contrôleurs minces, une isolation des tenants portée par la requête et non par la discipline, du travail en file, et des websockets qui poussent un signal plutôt que des données.

Une application Laravel de production, c’est une application où le framework a cessé d’être le sujet intéressant. Ce qui compte, c’est où vit la logique métier, comment un tenant est isolé, ce qui se passe hors de la requête, et comment le client apprend qu’une chose a changé — et Laravel apporte une réponse de premier ordre à chacun de ces points.

Contrôleurs minces, vraie couche service

Les contrôleurs lisent, valident et renvoient des codes de statut. Les services portent les règles métier et la frontière transactionnelle. Modèles et scopes parlent à la base. Résultat : une règle se teste sans démarrer HTTP, et un changement de forme de l’API n’atteint jamais le schéma.

Authentification via Laravel Sanctum, autorisations exprimées en policies plutôt qu’en conditions dispersées dans les contrôleurs.

Un multi-tenant qui échoue bruyamment

L’identité du tenant vient du token authentifié, jamais d’un paramètre que le client pourrait modifier. Un global scope l’applique à chaque requête : un filtre oublié ne renvoie rien, au lieu des lignes d’un autre client.

C’est toute la différence entre un système réellement multi-tenant et un système qui a simplement une colonne tenant_id : l’isolation est une propriété de la couche de requête, pas de celui qui a écrit le dernier endpoint.

Files, planificateur et Reverb

Notifications, rappels et demandes d’avis tournent sur un worker de file et un scheduler : rien de lent ne se produit dans une requête où quelqu’un attend.

Pour les écrans en direct, Laravel Reverb diffuse un petit signal « ceci a changé » sur un canal privé par tenant, et le client recharge. Pousser le signal plutôt que la donnée garde l’autorisation à un seul endroit et le socket léger.

Ce qui garde le tout honnête

PHPUnit pour le comportement, Larastan pour les types que PHP ne vérifie pas seul, et Laravel Pint pour que le formatage ne soit jamais un commentaire de revue.

Voir l’étude de cas SalonSync pour tout cela en production : un SaaS multi-tenant pour salons de coiffure et barbershops.

Questions fréquentes sur le développement Laravel

Laravel convient-il à un SaaS en production, ou seulement aux prototypes ?

Il fait tourner des SaaS en production. Ce dont un SaaS a réellement besoin — authentification, policies d’autorisation, files, planificateur, migrations, websockets, tests — est natif plutôt qu’assemblé à partir de paquets. SalonSync est une plateforme multi-tenant en production construite ainsi.

Comment isoler les tenants dans une application Laravel ?

Un global scope sur chaque modèle appartenant à un tenant, alimenté par l’identité du token authentifié. Comme le scope s’applique à la couche de requête, un endpoint qui oublie de filtrer renvoie un ensemble vide plutôt que les données d’un autre client.

Quand déplacer un traitement vers une file Laravel ?

Dès que la personne à l’origine n’a pas besoin du résultat pour continuer : envoyer une notification, demander un avis, appeler une API tierce. La question est de savoir si un échec doit bloquer la réponse. Si non, cela appartient à une file avec reprises et table des jobs échoués.

Pourquoi diffuser un signal par websocket plutôt que la donnée ?

Parce que la donnée exigerait sa propre autorisation. Envoyer « quelque chose a changé sur ce canal » et laisser le client recharger via l’API normale fait que les permissions sont appliquées une seule fois, là où elles le sont déjà, et le socket ne transporte jamais rien qu’un auditeur ne devrait voir.