8

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.

ChampChris
  • 1,565
  • 5
  • 26
  • 44

3 Answers3

5

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.

Rytis I
  • 1,105
  • 8
  • 19
Eben Roux
  • 12,983
  • 2
  • 27
  • 48
  • I am assuming BC means Business Context. I do get what ur saying, this is brand new project so I just getting familiar with Saga's and setting up the endpoints and subscribers. Going to update my question with more information – ChampChris Jul 01 '16 at 01:12
  • BC is a Bounded Context, my bad :) --- Well, having an endpoint "fronting" the real base system, or 3rd party integration, really does help. These "fronting" endpoints should never know about, or interact with, other "base" endpoints. That would be the responsibility of the process endpoint. The process endpoint is responsible for all the interaction and co-ordination. This is true, anyway, for ***orchestration*** (which is what I prefer). In a ***choreographed*** system things may look different but I think you may end up dealing with some accidental complexity with choreography IMHO. – Eben Roux Jul 01 '16 at 07:03
2

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

Community
  • 1
  • 1
MeTitus
  • 3,390
  • 2
  • 25
  • 49
0

Is this just a single use case? I.e Creating a user profile?

I'm wondering why not just have a single command, CreateUserProfile that is then handled by a command handler that orchestrates the use case. Everything else would become events I.e. PaymentAccountCreated, EmailNotificationSent etc...

You could use this command to start a process manager if necessary, but it depends on what else you need to handle and how the external calls are being returned. I.e is it a simple request/response or does the external system call your API etc

tomliversidge
  • 2,339
  • 1
  • 15
  • 15