#9 - Une architecture CQRS en python: Schéma Général

#9 - Une architecture CQRS en python: Schéma Général
Photo by Dan Cristian Pădureț / Unsplash

Command, Query, Event, Bus, Dispatchers, Handler, Response...
et l'addition.

L'architecture que nous avons mis en place a été largement inspirée par un talk d'Arnaud Lemaire, que vous trouverez ici

Le gars va à fond la caisse dans sa conf et présente un nombre de concept assez hallucinant en 45 minutes, il est d'ailleurs impossible de tout comprendre au premier visionnage.

J'ai donc un peu poncé le machin, et j'ai fais une implémentation à partir de rien, en python, donc, afin de comprendre comment le tout se mettait en musique, l'occasion de repartager tout ça.

Avant de rentrer dans le détail de chaque composant, un grand merci à Arnaud donc, qui grâce a cette conférence ultra dense, nous a permis de nous lancer dans la bonne direction en posant les bases de notre architecture CQRS.  

Objectifs

Les objectif classiques d'une architecture CQRS, sont les suivants:

  • Séparation entre lectures et commandes
  • la mise en place de Cache pour les lectures
  • la mise en place de projection de data pour anticiper les productions de données
  • la possibilité de migrer vers de l'event sourcing

Par ailleurs le fait de lister les commandes et le requêtes de notre système va également nous permettre de quitter l'orientation CRUD / ressources qui  a tendance à engluer les systèmes  dans une complexité technique inutile.

Principe de fonctionnements généraux

Une commande va déclencher un traitement, pour changer l'état interne du système. Réserver un billet de train, est une commande par exemple.

Une Query va récupérer de l'information dans le système, par exemple, si on se trouve sur un site de voyage, lister les billets de train que l'on a commandé dans les 6 derniers mois, est une query.

Un Event (évènement) est émis dans le système ou depuis l'extérieur pour avertir d'un changement qui est arrivé.

Chacun de ces objets va donc véhiculer une intention au sein de notre système, pour déclencher des changements d'état ou des récupération d'info.

On peut donc maintenant assez facilement imaginer qu'un point de terminaison API, va uniquement créer une commande ou une query, pour que celle ci soit traitée par notre système.

Schéma de fonctionnement général

Le schéma est divisé en 3 sections, Infra, Application et Domaine, correspondant peu ou prou à de la clean architecture déjà présenté ici.

Les requêtes web arrivent dans la couche de gestion des endpoints, les commandes ou query correspondantes sont envoyées dans le système via les BUS appropriés.

Les BUS de middleware permettent de réaliser tout un tas de traitement transverses comme du log, un pattern Unit Of Work, de l'auth, du contrôle d'accès ou même du cache.

Après avoir traversé le BUS la commande est gérée par un handler, qui va s'appuyer sur la couche domaine pour déclencher les traitements métier.

Le prochain article détaillera le fonctionnement technique de la couche API Endpoint, basé sur Fastapi dans notre cas.