Pipeline Behaviors¶
Pipeline behaviors are cross-cutting middleware that wrap message handling. They form a chain similar to HTTP middleware: each behavior can run logic before and after the next handler, short-circuit the pipeline, or handle exceptions.
graph LR
Send["bus.invoke(request)"] --> B1[Behavior 1]
B1 --> B2[Behavior 2]
B2 --> Handler[Request Handler]
Handler --> B2
B2 --> B1
B1 --> Send
Defining a Behavior¶
Implement IPipelineBehavior[MessageT, ResponseT]:
Warning
Every behavior must call await call_next() to continue the pipeline. Omitting
this call short-circuits the chain — the actual handler never executes.
Global Behaviors¶
Register behaviors that apply to every message (requests and events) via MessagingConfig:
Global behaviors execute in the order they are listed.
Per-request Behaviors¶
Attach behaviors to a specific request type via bind_request:
Per-event Behaviors¶
Attach behaviors to a specific event type via bind_event:
Each event handler gets its own pipeline invocation — behaviors run independently per handler.
Execution Order¶
Behaviors execute in this order:
- Global behaviors (from
MessagingConfig.pipeline_behaviors, in order) - Per-message-type behaviors (from
bind_requestorbind_eventbehaviors=[...], in order) - Handler
The response then unwinds back through the chain in reverse order.
Further reading¶
- Requests — commands, queries, and request handlers
- Events — event definitions, handlers, and publishers
- Routing & Endpoints — route messages to background endpoints
- Message Bus — setup, interfaces, and complete example