J'essaie essentiellement de comprendre la notion de CQRS et les concepts connexes.
Bien que le CQRS n'intègre pas nécessairement la messagerie et la recherche d'événements, il semble être une bonne combinaison (comme on peut le voir avec de nombreux exemples / articles de blog combinant ces concepts)
Étant donné un cas d'utilisation pour un changement d'état pour quelque chose (disons pour mettre à jour une question sur SO), considéreriez-vous que le flux suivant est correct (comme dans les meilleures pratiques)?
Le système émet un UpdateQuestionCommand agrégé qui peut être séparé en quelques commandes plus petites: UpdateQuestion qui vise la racine d'agrégat de questions et UpdateUserAction (pour compter les points, etc.) ciblé sur la racine d'agrégats d'utilisateurs. Ceux-ci sont envoyés de manière asynchrone à l'aide de la messagerie point à point.
Les racines agrégées font leur travail et si tout se passe bien, déclenchez respectivement les événements QuestionUpdated et UserActionUpdated, qui contiennent un état qui est externalisé vers un magasin d'événements .. pour être persistant yadayada, juste pour être complet, pas vraiment le point ici.
Ces événements sont également placés dans une file d'attente pub / sub pour la diffusion. Tout abonné (parmi lesquels probablement un ou plusieurs projecteurs qui créent les vues de lecture) est libre de s'abonner à ces événements.
La question générale: est-il en effet de bonne pratique que les commandes soient communiquées point à point (ie: le récepteur est connu) alors que les événements sont diffusés (ie: le ou les récepteurs sont inconnus)?
En supposant ce qui précède, quel serait l'avantage / l'inconvénient de permettre la diffusion des commandes via pub / sub plutôt que point à point?
Par exemple: lors de la diffusion de commandes lors de l'utilisation de Saga, cela pourrait être un problème, car le rôle de médiation qu'une Saga doit jouer en cas de défaillance d'une des racines agrégées est entravé, car la saga ne sait pas à quelle racine agrégée participent pour commencer. .
D'un autre côté, je vois des avantages (flexibilité) lorsque la diffusion de commandes serait autorisée.
la source
Réponses:
Disclaimler: Je ne fais que mes premiers pas dans le monde CQRS, mais je peux offrir ma compréhension actuelle de la question et nous verrons si d'autres le confirment. Tout ce que j'écris ci-dessous a un thème sous-jacent "tel que je le vois" et ne fait pas autorité.
Le cas à 80%
Pour répondre à votre question, les commandes sont en effet une affaire point à point. Lorsqu'une commande entre dans un contrôleur (application Web MVC), ce contrôleur demande ensuite à un répartiteur de commandes de trouver un et un seul gestionnaire de commandes approprié et délègue le travail à ce gestionnaire.
Pourquoi ne pas publier?
C'est une question de responsabilité . Si quelque chose envoie une commande, il faut s'attendre à ce qu'elle soit exécutée. Si vous publiez simplement et espérez que quelque chose le récupère et y donne suite, rien ne garantit que ce sera le cas. Par extrapolation, vous ne savez pas non plus si plusieurs gestionnaires ne décident pas d'agir sur une commande, ce qui peut entraîner l'application de la même modification plusieurs fois.
Les événements, en revanche, sont de nature informative, et il est raisonnable de s'attendre à ce que zéro, deux ou plusieurs composants soient intéressés par un événement particulier. Nous ne nous soucions pas vraiment de la portée de la modification demandée.
Exemple
Cela pourrait être comparé à la vraie vie. Si vous avez trois enfants, entrez dans une pièce et criez simplement "Nettoyez la salle de bain", vous n'avez aucune garantie que quelqu'un le fera, et vous préviendrez si cela ne se fait pas deux fois (si vous avez des enfants obéissants, c'est ;-) Vous devriez s'en tirer mieux si vous affectez un enfant spécifique à faire ce que vous voulez faire.
Cependant, lorsque cet enfant a terminé son travail, il est commode de crier «la salle de bain a été nettoyée», de sorte que tous ceux qui veulent se brosser les dents savent qu'ils peuvent désormais le faire.
la source
When a command enters a controller (MVC webapp)
-? Utilisez-vous RESTful? ou certains points de terminaison API hybrides? Pourriez-vous ajouter un exemple s'il vous plaîtexample.com/api/Post/AddPostComment
.Je suis d'accord qu'un système initiateur ne s'attendrait généralement pas à ce qu'une commande soit exécutée par plusieurs systèmes cibles:
acknowledgement
et réussiscompletion
oufailure
peuvent être publiés par le système ciblé pour informer l'initiateur). système).Il y a cependant encore du mérite à pouvoir souscrire des consommateurs supplémentaires (non transactionnels et généralement assez «promiscuité») qui «écoutent» les commandes émises entre les systèmes
la source