Edition 0 Updated to asp. Net core 0


Domain events versus integration events



Yüklə 11,82 Mb.
Pdf görüntüsü
səhifə199/288
tarix12.07.2023
ölçüsü11,82 Mb.
#136458
1   ...   195   196   197   198   199   200   201   202   ...   288
Domain events versus integration events 
Semantically, domain and integration events are the same thing: notifications about something that 
just happened. However, their implementation must be different. Domain events are just messages 
pushed to a domain event dispatcher, which could be implemented as an in-memory mediator based 
on an IoC container or any other method. 
On the other hand, the purpose of integration events is to propagate committed transactions and 
updates to additional subsystems, whether they are other microservices, Bounded Contexts or even 
external applications. Hence, they should occur only if the entity is successfully persisted, otherwise it’s 
as if the entire operation never happened. 
As mentioned before, integration events must be based on asynchronous communication between 
multiple microservices (other Bounded Contexts) or even external systems/applications. 
Thus, the event bus interface needs some infrastructure that allows inter-process and distributed 
communication between potentially remote services. It can be based on a commercial service bus, 
queues, a shared database used as a mailbox, or any other distributed and ideally push based 
messaging system. 
Domain events as a preferred way to trigger side effects across 
multiple aggregates within the same domain 
If executing a command related to one aggregate instance requires additional domain rules to be run 
on one or more additional aggregates, you should design and implement those side effects to be 
triggered by domain events. As shown in Figure 7-14, and as one of the most important use cases, a 
domain event should be used to propagate state changes across multiple aggregates within the same 
domain model. 
Figure 7-14. Domain events to enforce consistency between multiple aggregates within the same domain 


230 
CHAPTER 6 | Tackle Business Complexity in a Microservice with DDD and CQRS Patterns 
Figure 7-14 shows how consistency between aggregates is achieved by domain events. When the user 
initiates an order, the Order Aggregate sends an 
OrderStarted
domain event. The OrderStarted 
domain event is handled by the Buyer Aggregate to create a Buyer object in the ordering 
microservice, based on the original user info from the identity microservice (with information provided 
in the CreateOrder command). 
Alternately, you can have the aggregate root subscribed for events raised by members of its 
aggregates (child entities). For instance, each OrderItem child entity can raise an event when the item 
price is higher than a specific amount, or when the product item amount is too high. The aggregate 
root can then receive those events and perform a global calculation or aggregation. 
It’s important to understand that this event
-based communication is not implemented directly within 
the aggregates; you need to implement domain event handlers. 
Handling the domain events is an application concern. The domain model layer should only focus on 
the domain logic

things that a domain expert would understand, not application infrastructure like 
handlers and side-effect persistence actions using repositories. Therefore, the application layer level is 
where you should have domain event handlers triggering actions when a domain event is raised. 
Domain events can also be used to trigger any number of application actions, and what is more 
important, must be open to increase that number in the future in a decoupled way. For instance, when 
the order is started, you might want to publish a domain event to propagate that info to other 
aggregates or even to raise application actions like notifications. 
The key point is the open number of actions to be executed when a domain event occurs. Eventually
the actions and rules in the domain and application will grow. The complexity or number of side-
effect actions when something happens will grow, but if your code were coupled with “glue” (that is, 
creating specific objects with 
new
), then every time you needed to add a new action you would also 
need to change working and tested code. 
This change could result in new bugs and this approach also goes against the 
Open/Closed principle
 
from 
SOLID
. Not only that, the original class that was orchestrating the operations would grow and 
grow, which goes against the 
Single Responsibility Principle (SRP)

On the other hand, if you use domain events, you can create a fine-grained and decoupled 
implementation by segregating responsibilities using this approach: 
1.
Send a command (for example, CreateOrder). 
2.
Receive the command in a command handler. 

Execute a single aggregate’s transaction.

(Optional) Raise domain events for side effects (for example, OrderStartedDomainEvent). 
3.
Handle domain events (within the current process) that will execute an open number of side 
effects in multiple aggregates or application actions. For example: 

Verify or create buyer and payment method. 

Create and send a related integration event to the event bus to propagate states across 
microservices or trigger external actions like sending an email to the buyer. 

Handle other side effects. 


231 
CHAPTER 6 | Tackle Business Complexity in a Microservice with DDD and CQRS Patterns 
As shown in Figure 7-15, starting from the same domain event, you can handle multiple actions 
related to other aggregates in the domain or additional application actions you need to perform 
across microservices connecting with integration events and the event bus. 
Figure 7-15. Handling multiple actions per domain 
There can be several handlers for the same domain event in the Application Layer, one handler can 
solve consistency between aggregates and another handler can publish an integration event, so other 
microservices can do something with it. The event handlers are typically in the application layer, 
because you’ll use infrastructure objects like repositories or an application API for the microservice’s 
behavior. In that sense, event handlers are similar to command handlers, so both are part of the 
application layer. The important difference is that a command should be processed only once. A 
domain event could be processed zero or 
n
times, because it can be received by multiple receivers or 
event handlers with a different purpose for each handler. 
Having an open number of handlers per domain event allows you to add as many domain rules as 
needed, without affecting current code. For instance, implementing the following business rule might 
be as easy as adding a few event handlers (or even just one): 
When the total amount purchased by a customer in the store, across any number of orders, exceeds 
$6,000, apply a 10% off discount to every new order and notify the customer with an email about that 
discount for future orders. 

Yüklə 11,82 Mb.

Dostları ilə paylaş:
1   ...   195   196   197   198   199   200   201   202   ...   288




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©azkurs.org 2024
rəhbərliyinə müraciət

gir | qeydiyyatdan keç
    Ana səhifə


yükləyin