@super-dev.app · Full-stack · ★ ouvert aux missions
12,8k abonnés·47 vidéos·Actif depuis 2017
Développeur full-stack .NET / Angular avec une casquette DevOps sur Azure Cloud. Aussi à l'aise sur Flutter + Firebase. Je construis des produits, je les déploie, je les surveille.
Dès qu'on prononce CQRS , beaucoup d'équipes sortent l'artillerie lourde : event sourcing, bus de messages, deux bases de données. Pourtant CQRS, c'est d'abord une idée modeste — séparer les lectures des écritures — qu'on peut appliquer sans aucune usine à gaz, en organisant le code par vertical slices .
Découper par fonctionnalité, pas par couche
L'architecture en couches éclate une fonctionnalité dans cinq dossiers : Controllers , Services , Repositories , DTOs , Validators . Pour comprendre « créer une commande », on saute de fichier en fichier. La vertical slice inverse la logique : un dossier par fonctionnalité, tout ce qui la concerne au même endroit.
Bash
1Features/
2Orders/
3CreateOrder.cs# commande + handler + validateur
4GetOrderById.cs# requête + handler
5ListOrders.cs
Chaque slice est autonome. On la lit de haut en bas, on la supprime sans effet de bord, et deux slices ne partagent que le domaine — jamais un « service » fourre-tout.
Commande et requête, deux intentions distinctes
Une commande modifie l'état et ne renvoie (idéalement) qu'un identifiant. Une requête ne lit rien d'autre que ce dont la vue a besoin, souvent en court-circuitant le domaine pour projeter directement vers un DTO. Les modéliser séparément clarifie l'intention :
Le handler reste mince : il orchestre, il ne raisonne pas. La logique métier vit dans Order.Create , pas dans le handler — sinon on a juste déplacé le « service » dans un autre fichier.
Le médiateur, optionnel
On voit souvent CQRS collé à MediatR . Le médiateur découple l'endpoint du handler et offre un point d'accroche pour les pipeline behaviors (validation, logging, transaction). C'est pratique, mais ce n'est pas CQRS : on peut très bien injecter le handler directement.
5returnTypedResults.Created($"/orders/{id}", new { id });
6});
Si l'application est petite, sauter le médiateur et appeler le handler à la main reste parfaitement légitime — moins d'indirection, moins de magie.
Ne pas sur-concevoir
La question à se poser à chaque slice : ai-je vraiment besoin de ça ? Bases séparées, projections asynchrones, event sourcing — ce sont des réponses à des problèmes d'échelle précis (lectures massivement supérieures aux écritures, audit immuable). Sans ce problème, ils n'ajoutent que de la latence et des bugs de cohérence. Le bon CQRS, dans 90 % des cas, c'est : commandes et requêtes distinctes, un seul DbContext , des slices lisibles.
CQRS n'est pas une architecture, c'est une discipline de nommage . Séparez les intentions, gardez les handlers minces, et n'ajoutez un bus de messages que le jour où une métrique vous y force.