Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intention of Commands and Events in CQRS w/ ES

My question is related to this one. While the related question and answers show why we want to separate them, I wanted to make sure my understanding of the intent was correct. In all the examples I've seen, it seems that the intention of a command is that it can be rejected and that it updates the object in memory and the event will then update the database. Now I know I'm grossly over-simplifying here but is it correct to understand it that commands are meant to update memory and events update the DB? If not, could someone please clarify for me.

I'm trying to learn these patterns and this is how I'm grasping it so far and I want to make sure it's correct. Thanks in advance.

like image 356
Alexander Kahoun Avatar asked Dec 27 '22 09:12

Alexander Kahoun


2 Answers

Your understanding is correct.

Commands are issued against the domain model and ask for a specific behaviour. The domain model checks if the execution is allowed and behaves accordingly. Commands can be viewed as a specific use case that should be executed.

Events on the other hand simply announce that something has already happened (they can't be rejected since you can't change the past.)

Based on these events your application (as well as other applications in an integration scenario) can react accordingly -- like for instance update the read model database.

Specifically when the Event Sourcing pattern is applied, then the Events are what is being stored and replayed to rehydrate your domain model when needed.

like image 76
Dennis Traub Avatar answered Apr 06 '23 01:04

Dennis Traub


First, I don't think you are over simplifying it. It is a simple concept.

Commands tell your application to do something.

Events announce to the world that you did something.

If your application can't do what it is told to do (because of business rules or some other reason) It doesn't do it. And in turn doesn't announce anything. If it does do something then it announces it via an event.

If anyone is subscribed to those events, and care when they occur, then they can update their application with the data in the event.

In practice this generally means your read model subscribes to the events and updates itself accordingly.

Take creating a User. You issue a User_CreateCommand which contains information about a user. The command handler would then create a new object, that object being a User, and save it to the repository. Creating the user fires a User_CreatedEvent which will be handled by your read model and the read model will be updated. Any other systems listening can update themselves as well.

The part that takes a little bit of study is the fact that when you save your User to the repository, you aren't actually saving a User Object like you might think. You are actually saving the User_CreatedEvent which contains all of the data about the user.

Later, when you need your user object you would call something like _repo.GetById(1);

This would then replay all of the events dealing with that user and create the user object.

Hope that helps :)

like image 26
Brett Allred Avatar answered Apr 05 '23 23:04

Brett Allred