Search⌘ K
AI Features

Domain Events: Efficient System Adaptation

Explore the use of domain events in Golang to encapsulate important system changes and decouple event handling from domain logic. Understand how to implement aggregates, event dispatchers, and event handling interfaces to manage side effects like notifications and rewards effectively while maintaining clear modular design.

A domain event is a domain-driven design pattern that encapsulates a change in the system that is important to the domain experts. When important events happen in our system, they are often accompanied by rules or side effects. We may have a rule that when the OrderCreated event happens in our system, we send a notification to the customer.

If we put this rule into the handler for CreateOrder so that the notification happens implicitly, it might look something like this:

// orderCreation
if err = h.orders.Save(ctx, order); err != nil {
return errors.Wrap(err, "order creation")
}
// notifyCustomer
if err = h.notifications.NotifyOrderCreated(
ctx, order.ID, order.CustomerID,
); err != nil {
return errors.Wrap(err, "customer notification")
}
Sending a notification to the customer when order is created

If it were to remain as just one rule, we may be fine doing it this way. However, real-world applications rarely stay simple or have simple rules. Later, in the life of the application, we want to add a Rewards module to our application, we add the code for the rule to the same handler, and later, still we want more side effects to occur. What we had before, CreateOrder, should now be renamed CreateOrderAndNotifyAndReward...; otherwise, it won’t properly reflect its responsibility. Also, consider there will be other rules and handlers that might be implemented, so finding the implementations for a rule can become a problem.

Integrating domain events for system changes

Domain events will allow us to explicitly handle system changes, decoupling the work of handling the ...