Skip to main content

Domain Event

Domain Event captures a business-significant occurrence as an explicit, immutable object so reactions are decoupled from the trigger. It enables audit trails, cross-aggregate consistency, and event-driven integration with care around delivery.

Type
Data
When to Use
React To Domain Changes, Decouple Side Effects, Audit And Integration

Domain Event is a domain-driven design pattern that represents something meaningful that happened in the business domain as an explicit, named object. Instead of burying side effects inside the code that causes a change, the domain raises an event such as OrderPlaced or PaymentReceived, and interested parts of the system react to it. This makes important occurrences first-class concepts and decouples the action from its consequences.

How It Works

A domain event is a small, immutable object, often modeled as a value object, that records what happened, when, and the relevant data, expressed in past tense and domain language. When an aggregate performs a state change worth announcing, it creates the event and records it. After the change is committed, a dispatcher delivers the event to handlers that carry out reactions: sending email, updating a read model, integrating with another system. Dispatch may be in-process and synchronous, or published to a message broker for asynchronous, cross-service consumption.

Separating the fact that something happened from how the system responds keeps aggregates focused on their own invariants while still triggering broader workflows.

When to Use It

Use Domain Events when a state change in one part of the domain should trigger behavior elsewhere, when you want to decouple side effects from core logic, or when you need an audit trail of business-significant occurrences. They are central to event-driven architectures, integration between bounded contexts, eventual consistency across aggregates, and building read models.

Trade-offs

Events introduce indirection that can make the flow of a feature harder to trace, since the cause and its effects live in different places. Reliable delivery is a real concern: handlers may need transactional outbox techniques so an event is never lost or double-processed, and asynchronous handlers must be idempotent. Designing events at the right granularity is subtle, too fine and they overwhelm, too coarse and they lose meaning. Versioning event schemas over time also requires care.

Related Patterns

Event Sourcing goes further by persisting domain events as the system of record and rebuilding state from them. Publish-Subscribe is the delivery mechanism for events that cross process boundaries. Value Object is the typical shape of an event, immutable and compared by value. Domain Events also enable the saga pattern's choreography style.

Example

When an order is confirmed, the Order aggregate raises an OrderConfirmed event carrying the order id and total. One handler sends a confirmation email, another updates the analytics read model, and a third publishes the event for the shipping service. The order aggregate stays focused on its own rules while the rest of the system reacts independently.