Nous proposons d'aborder le design pattern Event sourcing qui peut s'avérer redoutable quand il est bien utilisé pour s'assurer de l'intégrité de ses données et pouvoir remonter le temps. À utiliser selon le besoin de votre projet.
Cas pratique d'Event Sourcing
En quelques mots, ce patron de conception propose de remplacer le schéma classique consistant à n'enregistrer en base que les informations de nos modèles/entités tels qu'ils sont actuellement par un système d'événements qui bout à bout forment des objets complets.
Sans event sourcing : j'ai en base une commande payée le 28/08/XXXX avec un panier de 30€ composé du produit #12 et du produit #15.
Avec event sourcing : j'ai une suite d'événements qui pourraient ressembler à ça :
- L'utilisateur #123 a ajouté le produit #12 à son panier à telle date
- Il a ajouté le #14 à tel autre moment
- il a ajouté le #15
- il a finalement supprimé le #14
- il a essayé de payer, mais a essuyé un refus de sa banque
- il a fini par terminer son paiement en utilisant une autre carte
Dans les deux cas, nous nous retrouvons avec une commande qui indique que l'utilisateur #123 a acheté le produit #12 et #15, mais dans le premier nous n'avons que les informations de la commande une fois terminée, dans l'autre nous avons les détails du chemin par lequel l'utilisateur est passé.
Pour mettre ce pattern en place, il faut définir avec les équipes en charges du projet quels sont les événements métiers que l'utilisateur peut déclencher en parcourant l'application (ajouter un produit au panier, accéder au checkout, valider un paiement, demander un remboursement, etc.).
Lorsqu'un utilisateur déclenche un de ces événements, cet événement est enregistré dans une base de données qui en principe est séparée de la base principale, avec la date et toutes les informations relatives à l'événement (le produit ajouté, la quantité etc.) permettant de rejouer l'événement plus tard.
Les événements associés à ce que l'on appelle des projecteurs sont rejoués à la demande, un par un, pour reconstituer dans notre exemple un objet commande complet. C'est cette suite d'événements qui va définir notre source de vérité pour garantir l'intégrité des données.
On parlera d'event sourcing pur si les données ne sont enregistrées que dans les événements (je ne peux pas avoir le statut de ma commande sans rejouer l'intégralité des événements qui y sont liés). C'est le cas de Git par exemple; pour avoir la dernière version de mon projet, Git rejoue les commits un par un. On parlera à l'inverse d'event sourcing hybride si en parallèle on sauvegarde les données calculées d'une manière plus simple, sans historique. Le format hybride permet de développer la majorité de son projet de manière conventionnelle en faisant des requêtes sur les tables de nos objets sans se soucier du fait qu'il existe une autre base qui stocke des événements.
Quand utiliser l'event sourcing ?
Disclamer
Attention, ce pattern est plutôt lourd à implémenter et requiert un temps d'adaptation pour les nouveaux intervenants qui rejoindraient un projet. Un bug au niveau de l'enregistrement des données d'un événement peut être fatal et conduire à un objet corrompu, inutilisable. Modifier à la main les données enregistrées dans un événement revient à remonter le temps pour changer le cours du présent et ça Marty on sait que c'est touchy !
Il est plutôt déconseillé d'utiliser ce pattern si ce n'est pas motivé par un réel besoin métier derrière.
Ceci étant dit, voyons les cas les plus évidents dans lesquels ce pattern est encouragé :
- Besoin de traçabilité : typiquement notre exemple de e-commerce où l'on veut savoir tout ce qu'il s'est passé, historiser les prix des produits au moment de la commande, optimiser ses tunnels de conversion etc.). Cela peut aussi être un besoin de règlementation strictes imposant d'avoir un historique complet (santé, finances par exemple)
- Besoin de reporting : Pourquoi pas générer des graph à partir de tous les événements enregistrer (taux de conversion, abandon de panier etc.)
- Besoin de remonter dans le temps : Si vous développez une application, un jeu avec un besoin d'annuler la ou les dernières actions, l'event sourcing peut s'avérer très pratique.
Notons qu'il n'est pas nécessaire de réaliser tout un projet en event sourcing. Il est possible de définir les modèles et actions qui nécessitent cette historisation et de garder le reste au format conventionnel.
Pour aller plus loin, je vous invite à écouter cet échange entre Brent Roose de JetBrains et Seb de Spatie et si vous avez le temps, ce cours complet appliqué à Laravel avec exemples de code.