Middleware API Reference
Summary
This page is a reference for the Postboy middleware API surface: the middleware base type, the pipeline context, decisions (Continue / Interrupt), stages (Publish / Callback / Execute), and the middleware service behavior (ordering, cancellation, and disposal).
Use this page when you need exact signatures and behavioral contracts. For “why” and “when”, see the Concepts and How-to pages.
Applies to
Postboy version line: middleware available since v3.5 (as introduced in your documentation set).
Terminology (reference)
Stage: which operation lane is currently executing (Publish / Callback / Execute).
Context: the object passed into middleware that contains stage and message.
Decision: what middleware returns from
beforeto allow or interrupt execution.Middleware chain: the ordered list of middleware instances attached to a bus.
PostboyMiddleware
Overview
Postboy middleware is implemented by extending/implementing the PostboyMiddleware contract.
Constructor
new PostboyMiddleware(name?)
Parameters | Name | Type | Required | Description | |------|------|----------|-------------| | name | string | no | A human-friendly name for diagnostics. If omitted, defaults to the class name. |
Notes
The middleware name is used in cancellation diagnostics (“cancelled by middleware …”).
Use a stable name if you want reliable searchability in logs.
Property: name
name: string
Description A stable identifier for the middleware instance, used for diagnostics and cancellation messages.
Method: canHandle(context)
canHandle(context: PipelineContext): boolean
Purpose Filter hook. Controls whether this middleware participates in the current operation.
Parameters | Name | Type | Description | |------|------|-------------| | context | PipelineContext | Contains stage and message |
Return
true: middleware participates;beforeandaftermay be called (see rules below).false: middleware is skipped entirely for this operation.
Behavior
Called once per middleware per operation.
Should be fast and side-effect free.
Method: before(context)
before(context: PipelineContext): MiddlewareDecision
Purpose Pre-hook. Called before the stage operation executes. May interrupt (cancel) the operation.
Parameters | Name | Type | Description | |------|------|-------------| | context | PipelineContext | Contains stage and message |
Return A MiddlewareDecision object. See “MiddlewareDecision” reference below.
Behavior
Only called if
canHandlereturned true.If the returned decision is Interrupt:
the operation is cancelled immediately,
the underlying handler/subscribers are not invoked,
later middleware in the chain are not evaluated for this operation,
afteris not called for this operation.
Method: after(context, result?)
after(context: PipelineContext, result?: unknown): void
Purpose Post-hook. Called after a stage has completed successfully.
Parameters | Name | Type | Required | Description | |------|------|----------|-------------| | context | PipelineContext | yes | Contains stage and message | | result | unknown | no | Stage-dependent result value. Most relevant for Execute stage. |
Behavior
Only called if:
canHandlereturned true, andthe operation completed successfully (no interrupt, and completion reached the post phase).
Not guaranteed to run on cancellations and may not run on failures depending on where the failure occurs.
Method: dispose()
dispose(): void
Purpose Cleanup hook. Release long-lived resources owned by the middleware instance.
Behavior
Called when middleware is removed from the chain, and/or when the middleware service is disposed.
Should be safe and ideally idempotent (do not throw; avoid double-cleanup issues).
PipelineContext
Shape
PipelineContext<TMessage = PostboyMessage>is conceptually:
Field | Type | Description |
|---|---|---|
stage | MiddlewareStage | Current stage (Publish / Callback / Execute) |
message | TMessage | The message instance being processed |
Notes
Treat
contextas read-only.The message instance is the same object that will be delivered/executed if the operation proceeds.
MiddlewareStage
Enum values
MiddlewareStage.PublishMiddlewareStage.CallbackMiddlewareStage.Execute
Meaning
Stage | Meaning | Typical “result” in after |
|---|---|---|
Publish | Fire-and-forget broadcasting | none / undefined |
Callback | Request/response-style flow | stage-dependent, may be undefined |
Execute | Synchronous executor invocation | result value on success |
Notes
Use stage-first filtering in
canHandleto avoid running middleware unnecessarily.
MiddlewareDecision
Shape
MiddlewareDecisionis an object with at least:
Field | Type | Required | Description |
|---|---|---|---|
type | MiddlewareDecisionType | yes | Continue or Interrupt |
MiddlewareDecisionType enum values
MiddlewareDecisionType.ContinueMiddlewareDecisionType.Interrupt
Semantics
Decision | Effect |
|---|---|
Continue | Operation proceeds to the next middleware / handler execution |
Interrupt | Operation is cancelled immediately (see cancellation rules) |
PostboyMiddlewareService (execution semantics)
Responsibilities
The middleware service:
stores the ordered list of middleware instances
dispatches stage-specific hooks
enforces cancellation on Interrupt
disposes middleware when removed or when the service is disposed
Order of execution
Middlewares run in registration order.
For each middleware:
build context
call
canHandleif true → call
beforeif not interrupted → proceed
On successful completion of the stage:
iterate again in registration order and call
afterfor those wherecanHandleis true
Cancellation behavior
If any middleware returns Interrupt from before:
the service throws a cancellation error immediately
later middlewares are not evaluated for this operation
the stage operation does not run
Disposal behavior
removeMiddleware(m):removes the instance from the chain
calls
m.dispose()
dispose()on the service:calls
dispose()on all currently registered middlewareclears the chain
Cancellation error (diagnostics reference)
When an operation is cancelled by middleware, the thrown error contains diagnostic information such as:
stage
message id
middleware name
optional reason string
Use these fields to:
debug unexpected cancellations,
build user-facing error messages (if appropriate),
produce audit logs.
Behavioral matrix (quick lookup)
Hook | Called when | Can cancel? | Guaranteed to run? |
|---|---|---|---|
canHandle | every middleware, every operation | no | yes (unless middleware is not in chain) |
before | only if canHandle is true | yes (Interrupt) | no (skipped if canHandle false) |
after | only if canHandle is true AND operation reaches successful post phase | no | no (skipped on cancel; may be skipped on failures) |
dispose | when middleware removed or middleware service disposed | no | depends on lifecycle wiring; should be called for removed/disposed |
Diagram: full reference lifecycle for one operation
@startuml title Middleware chain reference lifecycle (single operation)
participant "Postboy" as Bus participant "Middleware #1" as M1 participant "Middleware #2" as M2 participant "Handler/Subscribers" as H
Bus -> M1: canHandle(context)? alt true Bus -> M1: before(context) -> decision alt Interrupt Bus --> Bus: throw cancellation error stop end end
Bus -> M2: canHandle(context)? alt true Bus -> M2: before(context) -> decision alt Interrupt Bus --> Bus: throw cancellation error stop end end
Bus -> H: run stage operation H --> Bus: success (result?)
Bus -> M1: after(context, result?) [if canHandle was true] Bus -> M2: after(context, result?) [if canHandle was true]
@enduml
Next steps
[Middleware: mental model and architecture placement][Middleware lifecycle and contract (concept)][Middleware stages (concept)][Interrupt/cancel semantics (concept)][How-to: attach middleware to Postboy]