Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

multiple commands for single process in CQRS

I have CQRS+ES designed application. This I am new the CQRS+ES world been reading on it for over the last year and it makes perfect sense but implementing perfect sense isnt always easy.

anyway my question or questions are:

what is the best way to contain a multiple command (step) process? i.e. registering a user these are the commands i want to fire in that process:

  1. CreateUserProfileCommand
  2. CreatePaymentAccountCommand
  3. SendEmailAddressVerificationCommand

I have looked at Saga's they look more start and stop then this process which is all continuous.

Of course chaining the steps of events can lead to replay nightmare.

UPDATE @EbenRoux
To add more information the CreatePaymentAccount should actually be named UpdateUserWithPpaymentAccount. I see the confusion in the naming. What this command actually does get a 3rd party and get a PaymentCustomerId that get attached to the User.

I get what your saying about Saga's and i was wondering if this process needed that.

Right now this application is just under way so all the Business Context (I am assuming is what you mean by BC) dont have thier one endpoints pub/sub standpoint. I would like to get there though.

like image 300
ChampChris Avatar asked Jun 30 '16 10:06

ChampChris


2 Answers

Keep in mind that commands are not replayed. At this stage of my understanding I regard system/domain messages to be different from the event used in event sourcing (ES). ES events are there to represent state. They should not get involved in any processing. They would never result in a command being executed or in any way leading to a command being executed. They are simply another way to persist the state of your domain model.

Your process manager (what is sometimes referred to as a saga) would be a first-class citizen in another process Bounded Context (BC) that coordinates the system messaging and its state can certainly also be stored using ES.

You can route the same messages (if you wish) to different endpoints from different source. For instance: from your front-end/integration layer you can send the CreatUserProfileCommand and the routing sends it to your process BC where the handler creates a new UserRegistrationProcess, stores the stream and sends the CreateUserProfileCommand that is now routed to the User BC.

From the User BC a UserProfileCreatedEvent is published that your process BC subscribes to and the UserRegistrationProcess is updated, the stream is saved, and a CreatePaymentAccountCommand is sent off to the Payment BC. Here is an example of a system message (event) that will probably have a structure somewhat different to anything produced for the ES side of things.

Now from the Payment BC the PaymentAccountCreatedEvent is published that is also subscribed to by the process BC and the SendEMailAddressVerificationCommand is sent to the relevant BC.

Quite a common pattern emerges.

You can therefore avoid any replay nightmare since the concerns are clearly separated.

like image 165
Eben Roux Avatar answered Sep 17 '22 07:09

Eben Roux


Events are not a nightmare they are just the way things work in real life. If you send post a letter you don't wait for the reply, you continue with your life and when there's a reply you pick up the letter and read it.

You could indeed use Saga.

  1. Initiate the saga with the CreateUserProfileCommand
  2. Publish a new event UserProfileCreatedStarted and have the Payments service listen to that event
  3. Make the registration saga subscribe to the "PaymentAccountCreatedEvent"
  4. Publish the UserProfileCommandCreated when the registration process is finished
  5. Publish "UserProfileCommandCreated" and complete the saga and
  6. Have your communications service subscribe to the UserProfileCommandCreated and send the email

Have a look at this example: Saga implementation patterns – variations

One of the things you want to avoid is coupling between the services, and that's exactly what happen when you use a lot of commands in the domain. Usually commands are generated from the user or internally by some "trigger" in the system, i.e.: ChargeMontlyInstallment

As for the event sourcing and since this is all new for you, have a look here:best event sourcing db strategy

like image 44
MeTitus Avatar answered Sep 18 '22 07:09

MeTitus