Oyun Kitabı
De CRUD (Créer, Lire, Mettre à jour, Supprimer) à CQRS (Command Query Responsibility Segregation) : le problème est le modèle, pas le code (DE Crud Creer Lire Mettre A Jour Supprimer A CQRS Command Query Responsibility Segregation Le Probleme Est Le Modele Pas Le Code)
Qu'est-ce que CQRS, quelle est la différence entre CRUD et CQRS et quand faut-il utiliser CQRS ? Un guide expliquant pourquoi un seul modèle ne suffit pas dans les grands systèmes.
CQRS- Anatomie des décisions
Partie 1 de 4
CQRS pas avec la syntaxe du framework ; Un livre d'ingénierie en quatre parties examinant les tensions liées à la décision, à l'échelle et à la production.
Pourquoi CRUD fonctionne-t-il très bien pendant des années ?
CRUD n'est pas mauvais. Si votre équipe est composée de trois personnes, vous développez un seul produit, et vous répondez à quelques centaines de demandes par jour ; Le flux Controller → Service → Repository → Database est une solution parfaite. C'est rapide, c'est clair, c'est facile de se mettre dans la tête d'un nouveau développeur.```text
İlk gün
Product
↓
Controller
↓
Service
↓
Repository
↓
Database
La casse vient de la croissance du produit, pas de la qualité du code. Au début, vous répertoriez uniquement les produits. Au bout de six mois, le marketing demande un filtre ; les ventes nécessitent un classement ; l'opération demande l'exportation ; la direction veut un tableau de bord. Le même modèle `Product` finit soudainement par servir vingt objectifs différents.text
Marketing → filtre
Sales → sorting
Operations→ export
Management→ analytics + dashboard
↓
aynı Product modeli
Son signe dans la vie de tous les jours est généralement un résultat innocent :```text
Bugün
GET /products → 10 ms
Altı ay sonra
GET /products
↓ Category
↓ Reviews
↓ Seller
↓ Campaign
↓ Discount
↓ Stock
↓ Warehouse
↓ Shipment
↓ Favorites
aynı endpoint, farklı ekranları beslemek için büyür
```Petit glossaire pour junior :```text
📦 Aggregate
İş kurallarını bir arada koruyan domain nesnesidir.
📦 Invariant
Her koşulda doğru kalması gereken iş kuralıdır.
📦 Transaction boundary
Ya hep ya hiç birlikte kaydedilmesi gereken işlemlerin sınırıdır.
📦 Projection
Bir olayı, okuma için hazırlanmış yeni bir görünüme dönüştüren işlemdir.
📦 Read model / DTO
Ekranın ihtiyacı kadar alan taşıyan, okumaya uygun veri görünümüdür.
```L'histoire de cet article part de ce point : CQRS réduit cette tension non pas en changeant de technologie, mais en donnant des intentions différentes aux différents modèles.
## Quand CRUD crée-t-il un goulot d'étranglement ?
Dans l’approche CRUD, lecture et écriture se rencontrent sur une même représentation. Le côté rédaction veut maintenir les règles, la cohérence et les transitions. Le côté lecture nécessite un filtrage rapide, de petits DTO, des champs de recherche, de tri et d'affichage conviviaux. Lorsqu’un seul modèle tente de répondre simultanément à ces besoins, deux types de coûts apparaissent.
Le premier est le coût technique. Pour un simple écran de liste, les relations agrégées sont chargées, des jointures inutiles sont créées et le coût d'accès aux données augmente. Le deuxième est le coût cognitif. L'ajout d'un champ corrige le rapport d'une équipe tout en affectant la règle de transaction d'une autre équipe.```text
100 kullanıcı
→ tek API + tek model
→ CRUD yeterli
5.000 kullanıcı
→ liste, filtre, rapor, iş akışı
→ modelin niyetleri çatışmaya başlar
100.000 kullanıcı
→ okuma ve yazma yükü asimetrik
→ tek model değişimin maliyetini artırır
```Ce flux ne se produit pas dans les mêmes proportions dans chaque projet. Le signal n’est pas le nombre d’utilisateurs ; On ne sait pas clairement à quelle responsabilité le modèle sert.
## CQS : La racine petite mais critique du CQRS
Le principe de séparation des requêtes de commande de Bertrand Meyer est simple : **Poser une question ne devrait pas changer la réponse.**
- La commande change d'état ; Il porte une intention et n'a pas besoin de renvoyer de valeur.
- La requête renvoie des informations ; Cela ne change pas l’état observable.
Cette discipline au niveau de la méthode rend la conception des API plus prévisible. `ApproveInvoice` est une commande ; `GetInvoiceSummary` est une requête. `UpdateInvoiceStatus`, bien que techniquement possible, cache l'intention du travail.
CQRS porte cette idée au niveau architectural. Le modèle Command préserve les règles métier et les invariants. Le modèle de requête produit la vue que l'utilisateur ou le système souhaite voir. Ils peuvent partager la même table ; Deux bases de données, Kafka ou Event Sourcing ne sont pas obligatoires.
## Là où un seul modèle entre en conflit
Considérons un système de réservation. Le côté écriture doit maintenir les règles de capacité, d’annulation, de paiement et de créneau horaire. Par conséquent, des frontières et des transactions fortes sont nécessaires. L'écran de gestion, quant à lui, souhaite voir rapidement le taux d'occupation du jour, les résumés par emplacement et les réservations à venir.
Nourrir ces deux intentions avec le même graphe d'entités se transforme généralement en ce flux naïf :```text
GET /reservations
→ Reservation aggregate + Customer + Payment + Availability
→ domain kurallarıyla iç içe sorgu
→ yavaş ve kırılgan liste ekranı
```La réponse du CQRS consiste à définir deux objectifs d'optimisation distincts :```text
Command: ReserveRoom
→ kapasiteyi doğrula
→ kuralları uygula
→ transaction içinde kaydet
Query: GetDailyOccupancy
→ sadece tarih, lokasyon ve sayıları oku
→ ekrana uygun DTO döndür
```Grâce à cette distinction, le modèle d'écriture peut évoluer en termes de précision et le modèle de lecture peut évoluer en termes d'exploration et de rapidité. Cela ne signifie pas que chaque requête sera O(1). Cependant, le coût se rapproche souvent du nombre de lignes et de champs dans la vue cible plutôt que de l'ensemble du graphique de domaine.
## Signaux de décision pour CQRS
Le CQRS n’est pas choisi parce qu’il est tendance. Les signaux suivants deviennent significatifs lorsqu’ils apparaissent ensemble dans le même contexte délimité :
1. **Interface basée sur les tâches :** Les utilisateurs font plus que simplement former `Create`, `Update` ; confirme, effectue une réservation, initie la livraison ou demande un remboursement. Les noms de commandes doivent porter le langage métier.
2. **Charge asymétrique :** Le trafic de lecture est nettement supérieur au trafic d'écriture et les exigences de requête sont différentes de la forme du modèle de domaine.
3. **Règle métier :** L'agrégat conserve plusieurs invariants ; une simple mise à jour des données ne permet plus de déterminer la décision commerciale.
4. **Rythme de changement indépendant :** Les besoins en matière d'interface utilisateur et de reporting évoluent plus rapidement que les règles du côté de la création.
5. **Contexte ouvert et délimité :** Le langage, l'appropriation et les critères de réussite du domaine qui mettra en œuvre la distinction sont clairs.
Il ne s’agit pas d’une liste de contrôle, mais d’une preuve pour la décision. Le signal le plus fort est généralement le suivant : si l’équipe négocie constamment pour changer à la fois le comportement et l’apparence de la même entité, le modèle effectue deux tâches différentes.
## Qu'est-ce que le CQRS n'est pas ?
Il existe cinq inadéquations qui rendent le CQRS inutilement coûteux.
- CQRS ne consiste pas à réécrire tout le système. Cela ne peut commencer que dans un contexte complexe et délimité.
- CQRS n'est pas deux bases de données physiques. Premièrement, une distinction logique peut être faite dans le code.
- CQRS n'est pas un sourcing d'événements. Ils peuvent être utilisés ensemble mais ne constituent pas des conditions préalables l’un pour l’autre.
- CQRS n'est pas une exigence du courtier de messages. Les gestionnaires en cours de processus peuvent suffire pour commencer.- CQRS ne consiste pas à transformer chaque écran en microservice.
Surtout dans les panneaux d’administration simples, les règles métier superficielles et le faible taux de modification, le CRUD classique est un meilleur choix. Moins de pièces signifie moins d’opérations et une intégration plus facile. La maturité architecturale ne dépend pas de la rapidité avec laquelle vous ajoutez CQRS ; Cela se mesure par la façon dont vous savez quand ne pas ajouter.
## Compromis : qu'est-ce que vous gagnez, qu'est-ce que vous payez ?
| Gains | Prix |
| --- | --- |
| Commandes avec une intention commerciale | Plus de modèles et de contrats |
| Requêtes rapides adaptées aux scénarios d'utilisation | Gestion des données dupliquées |
| Evolution indépendante de la lecture et de l'écriture | Flux supplémentaires à observer |
| Option de mise à l'échelle en charge asymétrique | Cohérence ultime dans la distinction physique |
Par conséquent, la décision du CQRS n'est pas un choix de cadre, mais une fonction de coût : la complexité structurelle que vous ajoutez doit être inférieure à la complexité de domaine et opérationnelle que vous supprimez.
## Un moyen sûr de commencer
Le passage le plus sûr commence par une séparation logique et non par une séparation physique. Séparez les noms de commandes et de requêtes par langage métier. Téléchargez les requêtes dans des DTO adaptés à l'affichage. Clarifiez la validation, l’autorité et les limites invariantes du côté du commandement. Prenez des mesures. Toutefois, en cas de goulot d'étranglement avéré en matière de lecture ou de besoin d'une mise à l'échelle indépendante, déplacez le modèle de lecture vers un référentiel distinct.
Cette approche établit un système d'apprentissage au lieu d'un saut architectural irréversible.
Nous explorerons cette distinction dans la section suivante : comment les pipelines de commandes et de requêtes, les comportements du médiateur, la limite de transaction et la sélection de la boîte d'envoi fonctionnent-ils ensemble ?
## Concepts les plus fréquemment confondus```text
❌ CQRS = Event Sourcing
❌ CQRS = Microservice
❌ CQRS = Kafka
❌ CQRS = Event-driven architecture
✓ Bunlar birbirinden bağımsız yaklaşımlardır.
✓ Birlikte kullanılabilirler; birbirlerinin şartı değildir.
```Considérez d’abord le CQRS comme une séparation des responsabilités. Une base de données, un courtier ou un flux d'événements distinct ne doit être ajouté que s'il répond à un besoin mesuré.
## Matrice de décision
| Taille | CRUD | CQRS |
| --- | --- | --- |
| Simplicité de démarrage du code | Élevé | Moyen |
| Facilité de maintenance, domaine simple | Élevé | Moyen |
| Échelle de lecture asymétrique | Limité | Fort |
| Règle de domaine dense | Cela devient de plus en plus difficile avec le temps | Des frontières plus visibles |
| Coût d'exploitation | Faible | Moyen en discrimination logique, élevé en discrimination physique |
Ce n'est pas un tableau de bord ; C'est un outil de décision qui rend le contexte visible. Pour un domaine simple, la grande simplicité de CRUD est un réel avantage.
> **CRUD n'est pas un problème pour les petits systèmes. Le problème est qu’un seul modèle tente de représenter simultanément différentes intentions. CQRS résout ce problème non pas en changeant la technologie, mais en séparant les responsabilités.**
FAQ
Frequently asked questions
Que signifie « De CRUD (Créer, Lire, Mettre à jour, Supprimer) à CQRS (Ségrégation des responsabilités des requêtes de commande) : le problème est le modèle, pas le code » ?
Qu'est-ce que CQRS, quelle est la différence entre CRUD et CQRS et quand faut-il utiliser CQRS ? Un guide expliquant pourquoi un seul modèle ne suffit pas dans les grands systèmes.
Quel est le principal point à retenir ?
Écriture CQRS → Commande → Gestionnaire → Référentiel → Lecture de la base de données → Requête → Gestionnaire → Lire le modèle / DTO ```
À qui s’adresse cet article ?
Pour les ingénieurs et les responsables techniques qui mettent en œuvre les décisions en matière d'architecture logicielle, de livraison et de production.
Principes d'ingénierie appris
- CQRS n’est pas un rejet de CRUD ; C’est prendre conscience qu’un seul modèle ne peut plus répondre à deux besoins différents.
- La distinction architecturale ne doit pas être appliquée au système dans son ensemble, mais au contexte délimité où se concentre la complexité.
- Un modèle est précieux si son coût est inférieur à la complexité du domaine qu’il résout.
Continuer la lecture
Continuer la lecture
Suivant en série
Comment fonctionne le pipeline CQRS (Command Query Responsibility Segregation) ? Anatomie du flux de commande et de requête
Qu’est-ce que le pipeline de requêtes CQRS ? Comment une requête HTTP se déroule-t-elle via Controller, MediatR, le comportement du pipeline, le…
Même série
CQRS (Command Query Responsibility Segregation) dans les systèmes distribués : événement, courtier et projection
Comment fonctionne CQRS dans les systèmes distribués ? Examinez les événements de domaine, le courtier de messages, la projection, la boîte d'envoi,…
Même série
CQRS (Command Query Responsibility Segregation) en production : cohérence, erreurs et stratégies de récupération
Comment CQRS fonctionne-t-il en toute sécurité dans un environnement de production ? Décalage de cohérence, événement en double, corruption de séquence,…