Events¶
An event (notification) represents something that has already happened. Unlike requests, events can have zero or more handlers — this is the fan-out pattern.
Defining Events¶
Event is a frozen dataclass with an auto-generated event_id (UUID):
Event provides a convenient default with an auto-generated UUID. For domain-driven designs
where you control event identity and metadata, build on INotification directly:
Event Handlers¶
EventHandler[TEvent] is an ABC with a handle method that returns None:
INotificationHandler[TEvent] is the protocol equivalent — use it when you cannot inherit from
EventHandler (e.g., a handler that implements multiple protocols).
Registration¶
Bind an event type to a list of handler types:
Handlers across modules
Multiple modules can bind handlers for the same event type. waku's MediatorRegistryAggregator
merges all registrations at application startup:
Both handlers will fire when OrderPlaced is published.
Publishing¶
Inject IPublisher and call publish. Prefer IPublisher over IMediator when you only need
to broadcast events — this enforces the principle of least privilege:
If no handlers are registered for an event type, publish is a no-op — it does not raise.
Domain events from aggregates
In domain-driven architectures, aggregates collect events internally. An infrastructure service bridges them to the mediator:
Event Publishers¶
The event publisher strategy controls how event handlers are invoked when you call
mediator.publish().
| Publisher | Behavior |
|---|---|
SequentialEventPublisher |
Handlers execute one after another. If a handler raises, subsequent handlers do not run. This is the default. |
GroupEventPublisher |
Handlers execute concurrently via anyio.create_task_group(). If any handler raises, the task group cancels remaining handlers and propagates the exception. |
Configure the publisher in MediatorConfig:
Tip
Use SequentialEventPublisher when handler ordering matters or when handlers share
transactional context. Use GroupEventPublisher for independent handlers that benefit
from concurrent execution.
Further reading¶
- Requests — commands, queries, and request handlers
- Pipeline Behaviors — cross-cutting middleware for request handling
- Mediator (CQRS) — setup, interfaces, and complete example
- Event Sourcing — event-sourced aggregates, deciders, and projections