Requests¶
A request is a frozen dataclass that describes an intent. Commands change state, queries read state — both are dispatched through the message bus to exactly one handler.
Defining Requests¶
waku provides two ways to define a request:
IRequest[TResponse] is a marker protocol with no required attributes. Implement it as a
frozen dataclass:
Tip
IRequest without a type argument defaults to IRequest[None] — use it for void commands.
Response types are plain frozen dataclasses -- no base class is needed:
Request Handlers¶
Each request type maps to exactly one handler. Subclass RequestHandler[TRequest, TResponse]
and implement the handle method:
Registration¶
Bind a request to its handler via MessagingExtension in the module's extensions list:
Dispatching¶
Inject ISender and dispatch requests. Prefer ISender over IMessageBus when you only need to
dispatch requests — this enforces the principle of least privilege.
invoke() — request/response¶
Returns the response type declared by the request's generic parameter:
If the request declares IRequest[None], invoke() returns None.
send() — fire-and-forget¶
Dispatches a request through the same handler and pipeline, but discards the return value. Use it for side-effect-only commands where the caller does not need a result:
How are handler dependencies resolved?
Constructor parameters like user_repo: UserRepository are resolved automatically by
waku's dependency injection system. Register the
implementation in your module's providers list.
Further reading¶
- Events — event definitions, handlers, and publishers
- Pipeline Behaviors — cross-cutting middleware for request handling
- Message Bus — setup, interfaces, and complete example