CQRS & Events Sourcing avec GCP (1/3) : Introduction

Renaud Chardin
CodeShake
Published in
4 min readJun 25, 2020

--

Cette série d’article à pour but de vous introduire deux design pattern d’architecture logiciel que sont le CQRS et l’ Event Sourcing. Ils sont souvent liés, par nature, mais peuvent être utilisés l’un séparément de l’autre. On les mettra ensuite en action dans les produits de la GCP

Command Query Responsibility Segregation (CQRS)

Comme se magnifique nom barbare le décris, le CQRS est un design pattern qui propose de faire une séparation entre les lecture et les écritures dans votre application. Cette séparation se fait au niveau du model de donnée, mais peut également se faire au niveau projet et des services qui le compose.
En effet il est possible, en plus de bien séparer le model de donnée, de réaliser un (micro) service qui s’occupe de toute la partie écriture et un autre qui s’occupe de la partie lecture.

CQRS Pattern Schema
source: ouarzy.com

On voit sur schéma la séparation au niveau de nos services et de nos modèle, mais si on suit notre logique, on peut également séparer les langages de programmation ainsi que le choix de base donnée.

source: sudonull.com

On peut remarquer ici qu’il y a deux bases de donnée, ce qui implique que, comme on l’a vu précédemment, on peut avoir des technologies différentes pour nos micro services, on peut également avoir plusieurs types de base de données (SQL/NoSQL) et il n’y a aucune contrainte technique à le faire.

Avantages :

  • Scalabilité et performance
  • Gestion d’accès concurrent
  • Définition des modèles simplifiés

Inconvénients :

  • Synchronisation des modèles
  • Maintenance et administration plus complexe
  • Consistance des données de lecture pas garanti à 100%

Event Sourcing

L’event sourcing est également un design pattern qui a lui pour but de ne plus baser ça source donnée sur un état complet d’un objet, mais sur les événements arrivés sur cette objet. Cela veut dire que notre source de vérité n’est plus l’objet en lui même, mais chacun des événements de son cycle de vie, stocké dans un “Event Store”. En partant de ce principe, il y a deux règles d’or : l’event store est “append only” et il est interdit d’altérer un event. Concernant la seconde règle, cela implique que si il y a une erreur il faudra un event de correction pour rectifier l’erreur.

source: freecodecamp.org

Avantage:

  • Performance, no dead lock et scalable (append only)
  • Audit trail par design
  • Simple à comprendre pour le business
  • Flexible, pas de dépendance vers le model de lecture
  • Consultation de l’état d’un objet dans le passé

Inconvénients:

  • Peut être difficile à appréhender côté développement
  • L’agrégation de plusieurs store peut être complexe
  • Les modifications de modèle sont plus complexe
  • Il faut commencer le projet avec ce pattern

CQRS et Event Sourcing

Pourquoi ces deux patterns sont si souvent présentés conjointement ? On remarque après leurs descriptions qu’ils se complètent quasi parfaitement, en effet la partie écriture (command) va résulter d’un event et on va stocker cet event dans un event store. Pour la partie lecture, nous avons deux choix : soit lire l’event store, reconstituer un état à partir de tout les events précédent et le présenter, soit créer un système de dénormalisation. Cette couche de dénormalisation va intercepter un event, appliquer cette event sur l’état de d’objet concerner et le stocker dans une base de donner de lecture. ce principe permet de d’adapter ou créer plusieurs modèle de lecture, adapter et performant pour la lecture. La dénormalisation permet de restructurer notre objet et de le préparer à l’exposition extérieur : plus les données sont adaptées à la lecture, moins la donnée doit être traitée et plus la lecture est performant. Prenons l’exemple d’une api REST qui expose les données au format json, si la donnée de lecture est stocké dans une base de donnée NoSql type MongoDb, au format json, il n’y aura pas ou peu de transformation entre la DB et l’exposition REST, et on sera par conséquent très performant. Un bon schéma est toujours interessant pour illustrer un long discours.

source: clever-age.com

On introduit ici la notion de bus. Dans le cas du “command bus”, il est présent pour des raisons de scalabilité, mais “l’event bus” est très important, c’est lui qui permet cette dénormalisation en écoutant le bus des événements afin de répercuter chaque command à notre base de lecture. Passer par un bus permet également de créer plusieurs domaines de lecture sans avoir un impact sur l’existant. Il n’est donc pas interdit de créer plusieurs base de lecture pour different besoin, afin d’éviter du code compliqué et d’améliorer la performance et la sécurité sur les données exposées.

Avantages:

  • Scalabité
  • Performance
  • Flexibilité

Inconvénient:

  • Complexité de mise en place
  • Changement de paradigme pour le stockage de donnée

Dans l’étape 2, nous allons voir comment mettre en place notre Command Handler dans la GCP.

--

--

Renaud Chardin
CodeShake

Software Engineer & Team Leader @ SFEIRLuxembourg | Certified Kubernetes Application Developer