Module 93: Domain-Driven Design
Domain events
🏠The everyday picture
When a train leaves a station, an announcement goes out. The next station prepares, the catering team restocks, and the display boards update. The driver doesn't phone each of them; they react to the announcement.
📘What it really is
-
A domain event records something meaningful that happened in the business, named in the past tense in the ubiquitous language:
SessionBooked,PaymentReceived,SessionCancelled,TutorAvailabilityChanged. -
Events carry the facts others need (IDs, times, amounts), not instructions.
- Why they help:
- decoupling: scheduling raises
SessionBooked; billing, notifications and analytics react, without scheduling knowing about them; - rules across aggregates or contexts: "when payment is received, confirm the booking"; "when a session is cancelled late, charge the cancellation fee";
-
an audit trail of what happened and when (Module 56).
-
Publishing reliably: saving the aggregate and publishing the event must not get out of step (saved but not published, or published but not saved). The outbox pattern solves this: in the same database transaction, save the change and insert the event into an
outboxtable; a background worker then reads the outbox and publishes each event (Module 94), marking it sent. -
Handlers must be idempotent (Module 88): events can be delivered more than once.
- Within a modular monolith, events can be handled in-process or through the outbox and a job queue; across services, through a message broker (Module 94).
🖱️Try it
Add domain events to the booking platform: SessionBooked, PaymentReceived, SessionConfirmed, SessionCancelled. Implement an
outbox table written in the same transaction as the aggregate, and a worker that reads it every few seconds and calls handlers
(confirm booking on payment, send confirmation email, schedule a reminder). Make the email handler idempotent, and test by delivering
the same event twice.
✅Quick check
How are domain events named?
Show the answer
In the past tense, in the business's language, describing something that happened (for example, SessionBooked).
What problem does the outbox pattern solve?
Show the answer
It ensures a change and its event are saved together, so events are never lost or published for changes that didn't happen.
