11

I'm basically trying to wrap my head around the concept of CQRS and related concepts.

Although CQRS doesn't necessarily incorporate Messaging and Event Sourcing it seems to be a good combination (as can be seen with a lot of examples / blogposts combining these concepts )

Given a use-case for a state change for something (say to update a Question on SO), would you consider the following flow to be correct (as in best practice) ?

The system issues an aggregate UpdateQuestionCommand which might be separated into a couple of smaller commands: UpdateQuestion which is targeted at the Question Aggregate Root, and UpdateUserAction(to count points, etc) targeted at the User Aggregate Root. These are send asynchronously using point-to-point messaging.

The aggregate roots do their thing and if all goes well fire events QuestionUpdated and UserActionUpdated respectively, which contain state that is outsourced to an Event Store.. to be persisted yadayada, just to be complete, not really the point here.

These events are also put on a pub/sub queue for broadcasting. Any subscriber (among which likely one or multiple Projectors which create the Read Views) are free to subscribe to these events.

The general question: Is it indeed best practice, that Commands are communicated Point-to-Point (i.e: The receiver is known) whereas events are broadcasted (I.e: the receiver(s) are unknown) ?

Assuming the above, what would be the advantage/ disadvantage of allowing Commands to be broadcasted through pub/sub instead of point-to-point?

For example: When broadcasting Commands while using Saga's could be a problem, since the mediation role a Saga needs to play in case of failure of one of the aggregate roots is hindered, because the saga doesn't know which aggregate roots participate to begin with.

On the other hand, I see advantages (flexibility) when broadcasting commands would be allowed.

  • Well-written question btw. – Dav Jul 27 '12 at 7:41
17

Disclaimler: I'm only taking my first steps in the CQRS world, but I can offer my current understanding of the matter and we'll see if others confirm. All I write below has an underlying "as I see it" theme, and is not authoritative.

The 80% case

To answer your question, commands are indeed a point-to-point affair. When a command enters a controller (MVC webapp), that controller then asks a command dispatcher to find one and only one apropriate command handler, and delegates the work to that handler.

Why not publish?

It's a question of responsibility. If something sends a command, it entails expectation that it will be fulfilled. If you simply publish and hope that something somewhere picks it up and acts on it, there is no guarantee that this will be the case. By extrapolation, you also don't know if multiple handlers don't decide to act on a command, possibly resulting in the same change being applied more than once.

Events, on the other hand, are informative in nature, and it's reasonable to expect zero, two, or more components to be interested in a particular event. We don't really care in the scope of making the requested change.

Example

This could be compared to real life. If you have three children, walk into a room and simply shout "Clean the bathroom," you have no guarantee that someone will, and perhaphs if it won't be done twice (if you have obedient children that is ;-) You should fare better if you assign a specific child to do what you want done.

When that child finishes its job however, it's convenient if it shouts out "bathroom has been cleaned," so that everyone who wants to brush their teeth knows they can now do so.

  • makes a lot of sense. Excellent analogy :) – Geert-Jan Jul 27 '12 at 10:58
  • You lost me at.. When a command enters a controller (MVC webapp) - ? Are you using RESTful? or some hybrid API endpoints? Could you add an example please – Piotr Kula Sep 5 '18 at 9:24
  • @ppumkin we used a WebAPI endpoint that would be called by our web app every time it needed to execute a command. Eg. if user wanted to add a post comment, web app would sent a POST request to example.com/api/Post/AddPostComment. – Dav Sep 6 '18 at 10:28
0

I'm in agreement that an initiating system generally would never expect a command to be transacted by multiple target systems:

  • Commands are usually never 'send and pray' - the initiating system of a command generally wants asynchronous feedback as the progress and outcome of the command takes place (e.g. state events like acknowledgement, and successful completion or failure can be published by the targetted system to inform the initiating system).
  • If multiple target systems were involved, the initiating system would receive multiple (possibly contradictory) outcomes for the command (e.g. target 1 succeeded, but target 2 failed). This would require additional complexity in determining the actual state of the original command (e.g. would the command transaction be regarded as successful only if all targets succeeded? Would the command need to be rolled back or compensated in successful targets if one of the targets failed? etc.). This would introduce undesirable coupling and complexity between the initiating and target systems.

There is however still merit in being able to subscribe additional (non-transactional, and usually quite 'promiscuous') consumers who 'eavesdrop' on the commands issued between systems

  • Auditing purposes
  • Instrumentation and Operational metrics (e.g. load, business analytics, etc)
  • Complex Event Processing or Stream Event processing 'eavesdroppers' - these systems can detect errors or irregularities in the commands (e.g. frequency of commands, or correlation between different combinations of commands and events), and can trigger alerts, or corrective actions (often in the form of further, different types of commands).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.