Vous avez une application laravel, et vous commencez à avoir des clients, tout fonctionne parfaitement, tellement bien qu'un beau jour vous voulez ouvrir votre application aux clients de vos clients en marque blanche/grise.
Notre enjeu aujourd'hui est de rendre une application existante multi-instances (en anglais, multi-tenant), afin d'accueillir plusieurs installations paralléles. L'enjeu sera d'assurer une séparation des données clients, mais sans multiplier la taille du code ainsi que le temps de mantenance, et sans tout recoder.
C'est la base de notre feature: comment assurer la séparation des données de nos différents clients. Ici il y a plusieurs écoles qui dépendrons du degré de séparation que vous voulez.
D'un coté on peux séparer les bases de données. L'application aura donc une base par sous application, et changera sa configuration suivant l'instance voulue. C'est la solution qui offre la meilleure séparation car les bases ne sont même plus obligatoirement sur le même serveur. Par contre, si vous voulez une administration commune, ça sera difficile a mettre en place.
De l'autre on peux conserver la même base, mais ajouter à chaque champ un instance_id afin de séparer les instances les unes des autres. Il faudra ajouter une clause where à chaque requete et a chaque model, mais suivant votre framework, c'est facile a faire. Ici on a plus qu'une seule base à maintenir, tout en garantissant une séparation des données plutot systématique. Par contre, on a besoin d'ajouter du code dans l'application.
Dans notre cas précis nous avons choisi la seconde solution. L'avantage d'ajouter un instance_id rend l'approche "béte et méchante". Avec Laravel, cela se matérialise par l'existance d'une global scope sur nos models.
Un globalScope consiste a rajouter automatiquement une clause, à chaque requéte concernant le Model sur lequel le scope est actif. Ainsi, en quelques lignes de code, on rajoute automatiquement une WHERE instance_id = ? sur chaque requete.
Il ne reste plus qu'a configurer ce scope depuis un middleware, qui va, a partir du domaine, déterminer l'id d'instance à utiliser.
Et voila! Normalement avec cette approche on profite d'une application a plusieurs instances, quasiment sans changer notre code métier. Il faudra biensur adapter car certaines tables ne pourrons pas utiliser ce principe. Par exemple si vous voulez que les users servent a déterminer l'instance, vous ne pourrez pas scoper les utilisateurs en fonction de l'instance automatiquement.