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¶
IEvent is a protocol for event types. Implement it as a frozen dataclass:
For domain-driven designs where you control event identity and metadata, extend IEvent
with your own base class:
Event Handlers¶
EventHandler[TEvent] is an ABC with a handle method that returns None:
IEventHandler[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 MessageRegistryAggregator
merges all registrations at application startup:
Both handlers will fire when OrderPlaced is published.
Publishing¶
Inject IPublisher and call publish. Prefer IPublisher over IMessageBus 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 message bus:
Event Publishers¶
The event publisher strategy controls how event handlers are invoked when you call
bus.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 MessagingConfig:
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
- Message Bus (CQRS) — setup, interfaces, and complete example
- Event Sourcing — event-sourced aggregates, deciders, and projections