CQRS and DDD boundaries - domain-driven-design

I've have a couple of questions to which I am not finding any exact answer. I've used CQRS before, but probably I was not using it properly.
Say that there are 5 services in the domain: Gateway, Sales, Payments, Credit and Warehouse, and that during the process of a user registering with the application, the front-end submits a few commands, the same front-end will then, once the user is registered, send a few other commands to create an order and apply for a credit.
Now, what I usually do is create a gateway, which receives all pubic commands, which are then validated, and if valid, are transformed into domain commands. I only use events to store data and if one service needs some action to be performed in other service, a domain command is sent directly from one service to the other. But I've seen in other systems that event handlers are used for more than store data. So my question is, what are the limits to what event handlers can do? And is it correct to send commands between services when a specific service requires that some other service performs an action or is it more correct to have the initial event raise and event and let the handler in the other service perform that action in the event handler. I am asking this because I've seen events like: INeedCreditAproved, when I was hoping to see a domain command like: ApprovedCredit.
Any input is welcome.

You're missing an important concept here - Sagas (Process Managers). You have a long-running workflow and it's better expressed centrally.
Sagas listen to events and emit commands. So OrderAccepted event will start a Saga, which then emit ApproveCredit and ReserveStock commands, to be sent to Credit and Warehouse services respectively. Saga can then listen to command success/failure events and compensate approprietely, like say emiting SendEmail command or whatever else.

One year ago I was sending commands like "send commands between services by event handlers when a specific service requires that some other service performs an action" but a stupid decision made by me switched to using events like you said "to have the initial event raise and event and let the handler in the other service perform that action in the event handler" and it worked at first. The most stupid decision I could make. Now I am switching back to sending commands from event handlers.
You can see that other people like Rinat do similar things with event ports/receptors and it is working for them, I think:
http://abdullin.com/journal/2012/7/22/bounded-context-is-a-team-working-together.html
http://abdullin.com/journal/2012/3/31/anatomy-of-distributed-system-a-la-lokad.html
Good luck

Related

In DDD, are Commands strictly synchronous API calls?

When I read about Command in the DDD Context, it is usually described as an API call.
In this example, serviceA sends a command to serviceB.
serviceA -> serviceB
In my understanding, command is a concrete action on something. So technically this can come in asynchronous forms as well. Maybe sending a command message in a Message Queue.
serviceA -> queue -> serviceB
Are Commands strictly synchronous API calls, or can be asynchronous?
Commands in the context of domain-driven design:
Commands - in the context of domain-driven design - represent the intent for something to happen in the system that leads to some desired outcome after being executed. So it can be seen as some object that contains all the information required by the receiver of the command to execute the command.
So when talking about commands in domain-driven design there is no technical definition or restriction in what way a command can be triggered and transmitted or how the required information is represented.
Commands should be describable from the business perspective first to find out what or who in the system context will trigger it and when it will be triggered. As well as what the expected state shall be after the command has been executed.
Commands can be triggered/transmitted, for instance, the following ways:
Performing some synchronous REST request when a user clicks on a button on a web site
Sending an asynchronous message (e.g. from one Microservice) to the message queue of the command receiver (e.g. another Microservice)
Performing a gRPC call (e.g. from one Microservice to another)
Clicking on a button in the UI of a desktop application
Executing a scheduled background task
Commands in the business context can be, for instance:
Checkout the current shopping basket in an online shop to initiate the order
Upvote and answer on stackoverflow and increase the answer's vote
In the context of domain-driven design it is just some implementation detail if the command is executed synchronously or asynchronously. The important part is that the intended outcome will have happened after the executed has been performed successfully.
When performing a sychronous API call the component that triggered the command can get feedback via a synchronous answer if the command went through ok.
Whereas in an asynchronous command transmission (like messaging) you will only know that the message has been delivered to some queue but the successful execution of the command will have to be perceived in some other way. Either by querying for the current state of the involved domain entities or by leveraging some event-based mechanism where events get published after a command has been executed and any interested parties can subscribe to those events.
TL;DR
Getting back to your questions:
When I read about Command in the DDD Context, it is usually described as an API call.
The API call itself is just the technical data representation and transmission of the command.
Are Commands strictly synchronous API calls, or can be asynchronous?
The same command can be triggered in different ways (see previous examples) and again transmitted in different ways. But no matter how triggered or how transported it will have to contain the same required information and will lead to the same desired outcome in the overall system after being executed.
So, yes it can of course be asynchronous as well.

Should I put command bus between controller and domain service?

I am working on a backend and try to implement CQRS patterns.
I'm pretty clear about events, but sometimes struggle with commands.
I've seen that commands are requested by users, or example ChangePasswordCommand. However in implementation level user is just calling an endpoint, handled by some controller.
I can inject an UserService to my controller, which will handle domain logic and this is how basic tutorials do (I use Nest.js). However I feel that maybe this is where I should use command - so should I execute command ChangePasswordCommand in my controller and then domain module will handle it?
Important thing is that I need return value from the command, which is not a problem from implementation perspective, but it doesn't look good in terms of CQRS - I should ADD and GET at the same time.
Or maybe the last option is to execute the command in controller and then emit an event (PasswordChangedEvent) in command handler. Next, wait till event comes back and return the value in controller.
This last option seems quite good to me, but I have problems with clear implementation inside request lifecycle.
I base on
https://docs.nestjs.com/recipes/cqrs
While the answer by #cperson is technically correct, I would like to add a few nuances to it.
First something that may not be clear from the answer description where it advises to "emit an event (PasswordChangedEvent) in command handler". This is what I would prefer as well, but watch out:
The Command is part of the infrastructure layer, and the Event is part of the domain.
So from the command you should trigger code on the AggregateRoot that emits the event.
This can be done with mergeObjectContext or eventBus.publish (see the NestJS docs).
Events can be applied from other domain objects, but the aggregate usually is the emitter (upon commit).
The other point I wanted to address is that an event-sourced architecture is assumed, i.e. applying CQRS/ES. While CQRS is often used in combination with Event Sourcing there is nothing that prescribes doing so. Event Sourcing can give additional advantages, but also comes with significant added complexity. You should carefully weigh the pros and cons of having ES.
In many cases you do not need Event Sourcing. Having just CQRS already gives you a lot of benefits, such as having your domain / bounded contexts well-contained. Separation between reads and writes, single-responsibility commands + queries (more SOLID in general), cleaner architecture, etc. On a higher level it is easier to shift focus from 'how do I implement this (CRUD-wise)?', to 'how do these user requirements fit in the domain model?'.
Without ES you can have a single relational database and e.g. persist using TypeORM. You can persist events, but it is not needed. In many scenario's you can avoid the eventual consistency where clients need to subscribe to events (maybe you just use them to drive saga's and update read-side views/projections).
You can always start with just CQRS and add Event Sourcing later, when the need arises.
As your architecture evolves, you may find that you require a command bus if you are using Processes/Sagas to manage workflows and inter-aggregate communication. If and when that is the case, it will naturally make sense to use that bus for all commands.
The following is the method I would prefer:
execute the command in controller and then emit an event (PasswordChangedEvent) in command handler. Next, wait till event comes back and return the value in controller.
As for implementation details, in .NET, we use a SignalR websockets service that will read the event bus (where all events are published) and will forward events to clients that have subscribed to them.
In this case, the workflow would be:
The user posts to the controller.
The controller appends the command to the command bus.
The controller returns an ID identifying the command.
The client (browser client) subscribes to events relating to this command.
The command is received by the domain service and handled. An event is emitted to the event store.
The event is published to the event bus.
The event listener subscription service receives the event, finds the subscription, and sends the event to the client.
The client receives the event and notifies the user.

Can domain events be deleted?

In order to make the domain event handling consistent, I want to persist the domain events to database while saving the AggregateRoot. later react to them using an event processor, for example let's say I want to send them to an event bus as integration events, I wonder whether or not the event is allowed to be deleted from the database after passing it through the bus?
So the events will never ever be loaded with the AggregateRoot root anymore.
I wonder whether or not the reactor is allowed to remove the event from db after the reaction.
You'll probably want to review Reliable Messaging Without Distributed Transactions, by Udi Dahan; also Pat Helland's paper Life Beyond Distributed Transactions.
In event sourced systems, meaning that the history of domain events is the persisted history of the aggregate, you will almost never delete events.
In a system where the log of domain events is simply a journal of messages to be communicated to other "partners": fundamentally, the domain events are messages that describe information to be copied from one part of the system to another. So when we get an acknowledgement that the message has been copied successfully, we can remove the copy stored "here".
In a system where you can't be sure that all of the consumers have received the domain event (because, perhaps, the list of consumers is not explicit), then you probably can't delete the domain events.
You may be able to move them -- which is, instead of having implicit subscriptions to the aggregate, you could have an explicit subscription from an event history to the aggregate, and then implicit subscriptions to the history.
You might be able to treat the record of domain events as a cache -- if the partner's aren't done consuming the message within 7 days of it being available, then maybe the delivery of the message isn't the biggest problem in the system.
How many nines of delivery guarantee do you need?
Domain events are things that have happened in the past. You can't delete the past, assuming you're not Martin McFly :)
Domain events shouldn't be deleted from event store. If you want to know whether you already processed it before, you can add a flag to know it.
UPDATE ==> DESCRIPTION OF EVENT MANAGEMENT PROCESS
I follow the approach of IDDD (Red Book by Vaughn Vernon, see picture on page 287) this way:
1) The aggregate publish the event locally to the BC (lightweight publisher).
2) In the BC, a lightweight subscriber store all the event published by the BC in an "event store" (which is a table in the same database of the BC).
3) A batch process (worker) reads the event store and publish the events to a message queue (or an event bus as you say).
4) Other BCs interested in the event (or even the same BC) subscribe to the message queue (or event bus) for listening and react to the event.
Anyway, even the worker had sent the event away ok to the message queue, you shouldn't delete the domain event from the event store. Instead simply dont send it again, but events are things that have happened and you cannot (should not) delete a thing that have occurred in the past.
Message queue or event bus are just a mechanism to send/receive events, but the events should remain stored in the BC they were created and published.

CQRS/ES - Way of Communication between two Bounded Context

Hi I have a following scenario,
There is two seperate application
ShopManagament - This handle the registration of shop. Contaning aggregate
Shop and other aggregates
NotifyService - This send the mail , sms , notification. Contaning aggregate Email
, SMS , Nofication
The both application build using CQRS/ES with DDD.
Technology used to build the application is Spring with Axon and for messaging usign RabbitMQ
Step 1 -
A shop is registered by issue a command ShopRegisrtraionCommand (ofcourse this handle by the shop aggregate and change the status when event is fired) ,
which fire an event ShopRegistratedEvent .
Step 2 -
When shop ShopRegistredEvent is fired , then I have a EventHandler which listen ShopRegistredEvent and
send the SendEmailVerificationCommand (you can say a request or it act as request )to NotifyService.
Step 3 -
The same command (SendEmailVerificationCommand ) is also handle by the Shop aggregate and
then shop aggregates fire an event MailVerifcationSendedEvent,
this event changes the verification status of Shop to "MailInSendingProcess".
Step 4 -
On other side NotifyService handle that command (SendEmailVerificationCommand or request ) and send the mail ,
if the email successfully sent then NotifyService fire a VerificationEmailSent.
Step 5 -
VerificationEmailSentEvent (fired by NotifyService) is listen by ShopManagment Application using the event listener ,
then this event listener issue a VerificationMailSendedSuccesfullyCommand for the shop aggregates,
and then shop aggregate fire an event VerificationEmailDeliveredEvent , this changes the verifcation status "MailDelivered".
Step 6 -
If the mail sending failed due to any reasons , NotifyService fire another event VerificationEmailSendingUnsuccessfullEvent
which handle by ShopManagament event listener and issue a another command VerificationEmailUnsuccessfull to shop aggregate and then shop
aggregate fire an event VerficationMailSendingFailedEvent , this event change the status of verification status to "MailSendingFalied".
Here the two BC communicate using request and event.
Question -
Can we send command to other bounded context as I am sending in my application or there is another approach.
Is the tracking the status of the Email sending is part of Shop aggregate or I have to create the another aggregate like EmailVerifcation
because I have to resend the falied mail using the schedular.
Is any other way to manage this type of thing if happinning?
I have seen this back and forth between services for verification happen before, but it is typically a process I'd prefer to avoid. It requires intricate teamwork with services for something relatively simple; the intricacy will typically cause pain in the future.
Now to answering your questions:
This should be fine I'd say. A Command is nothing more then a form of message, just like queries or the events in your system. The downside might be that the command-sending Bounded Context should be aware of the 'language' the other Bounded Context speaks. Some form of anti corruption layer might be in place here. See of this as a service which receives the command-sending request of BC-1 in its language and translates it to the language of BC-2. From an Axon Framework perspective I'd also recommend to setting up the DistributedCommandBus, as it contains a component (the CommandRouter to be precise) which is aware of what commands which node might handle.
& 3. This wholly depends on how your domain is modeled. On face value, I'd say a Shop aggregate typically isn't aware of any emails being sent, so from that end I'd say 'no, don't include it in the aggregate'. A Saga would likely be a better fit to send a command to your NotifyService. That Saga would listen to the ShopRegistredEvent and as a response would publish the SendEmailVerificationCommand to the NotifyService. The Saga is able to either act on the callback of the SendEmailVerificationCommand or handle the VerificationEmailSentEvent and VerificationEmailSendingUnsuccessfullEvent to perform the required follow up logic after a (un)successful email.
Hope this gives you some insights Ashwani!

Domain driven design and domain events

I'm new to DDD and I'm reading articles now to get more information. One of the articles focuses on domain events (DE). For example sending email is a domain event raised after some criteria is met while executing piece of code.
Code example shows one way of handling domain events and is followed by this paragraph
Please be aware that the above code will be run on the same thread within the same transaction as the regular domain work so you should avoid performing any blocking activities, like using SMTP or web services. Instead, prefer using one-way messaging to communicate to something else which does those blocking activities.
My questions are
Is this a general problem in handling DE? Or it is just concern of the solution in mentioned article?
If domain events are raised in transaction and the system will not handle them synchronously, how should they be handled?
When I decide to serialize these events and let scheduler (or any other mechanism) execute them, what happens when transaction is rolled back? (in the article event is raised in code executed in transaction) who will cancel them (when they are not persisted to database)?
Thanks
It's a general problem period never mind DDD
In general, in any system which is required to respond in a performant manner (e.g. a Web Server, any long running activities should be handled asynchronously to the triggering process.
This means queue.
Rolling back your transaction should remove item from the queue.
Of course, you now need additional mechanisms to handle the situation where the item on the queue fails to process - i.e the email isn't sent - you also need to allow for this in your triggering code - having a subsequent process RELY on the earlier process having already occurred is going to cause issues at some point.
In short, your queueing mechanism should itself be transactional and allow for retries and you need to think about the whole chain of events as a workflow.

Resources