Domain-Driven Design – Should There Be Exactly One Event Per Command in CQRS?

cqrsdomain-driven-designevent-sourcing

I am looking for a way to design a ddd application with convention over configuration.

Say an aggregate "Client" has a command defined "FillProfile". It will logically raise an event "ProfileFilled".

Are there cases when a command will raise more than an event, or where a command will raise different events based on some logic? Or is this always a 1 – 1 relationship (1 command will always raise none, or a single event of a given type).

I am asking this because if this is a fact, that a command will always raise the same event, I can build my convention system on that fact. I know that "RaiseEvent" will result in "EventRaised"…

Best Answer

Since you tagged your question with "CQRS", I guess you mean events in a "CQRS & Event Sourcing" context, like it is described here. In this tutorial, the difference between events and commands is well explained:

  • events capture the elementary "things that can happen" in your system, from the system's point of view.

  • commands are defined by what the user considers as an operation, from his point of view

And though this often leads to a couple of commands and events with a 1:1 correspondence, these different points of view can lead to commands which fire more than one event, or different events depending on the command parameters. I can even imagine cases where a command does not raise an event at all, but that would be a very exceptional case, not a very typical one.

For example, the tutorial mentions events

  • TabOpened
  • DrinksOrdered
  • FoodOrdered

and commands

  • OpenTab
  • PlaceOrder

Here, the command "OpenTab" will lead to an event "TabOpened", but the command PlaceOrder will lead to the events "DrinksOrdered", "FoodOrdered", or both.

In fact, if you are designing a new system "from scratch", you can try to design it with a 1:1 correspondence between commands and events and look how well that scales when the system becomes bigger. You can even try a hybrid approach: a list of events and commands with a 1:1 correspondence, together with some additional, combined commands. Just try how far that leads you for the particular system you are designing.

Related Topic