Middleware Reference
Reference page for the middleware pipeline of @artstesh/postboy (applies to v3.5.x): the middleware base class, the pipeline types, decisions, and cancellation. For the conceptual model see Middleware; for cancellation in depth see Middleware cancellation; for the upgrade from the 3.4 single-hook interface see Migrating middleware from 3.4.
Every fire/fireCallback/exec passes through the pipeline. There is no handle() hook anymore — middleware is the abstract class below.
PostboyMiddleware
Member | Description |
|---|---|
| Readonly identifier used in cancellation diagnostics; defaults to the class name — set an explicit stable name for searchable logs |
| Filter consulted for both |
| Pre-hook; an |
| Post-hook; |
| Cleanup on removal and on bus disposal; keep it safe and idempotent |
Registration is message-driven: exec(new AddMiddleware(mw)) appends to the chain, exec(new RemoveMiddleware(mw)) removes by instance identity and calls mw.dispose(). Adding the same instance twice runs its hooks twice. See the Infrastructure Messages Reference.
MiddlewareStage
Stage | Meaning | Typical |
|---|---|---|
|
|
|
|
| emitted result values, once per emission |
| synchronous | the handler's return value |
Use stage-first filtering in canHandle (context.stage) to avoid running middleware unnecessarily — the pipeline also processes infrastructure messages.
MiddlewareDecision / MiddlewareDecisionType
Decision | Effect |
|---|---|
| The operation proceeds to the next middleware, then runs |
| The operation is cancelled immediately (see cancellation semantics) |
Cancellation is a control-flow stop at the bus boundary. It is not: a handler throwing during execution, a callback stream erroring later, or a subscriber unsubscribing — those are failures and runtime conditions, not middleware cancellation.
PipelineContext
Treat the context as read-only. The message instance is the same object that will be delivered or executed if the operation proceeds.
PipelineResult
PipelineResult is the outcome of one pass over the chain, produced and consumed internally by the middleware service. It is exported from the package root for typing purposes only — treat it as opaque and do not construct it.
CancelDetails / CancelError
Field of | Type | Description |
|---|---|---|
|
| The lane that was interrupted |
|
| The |
|
| The static |
|
| Namespace of the registrator, when relevant |
|
| Optional human-readable reason |
Detect it with error instanceof CancelError or error.name === 'PostboyCancelError' — an isCancelError helper exists in the sources but is not exported. Log stage, messageId, and middleware to debug unexpected cancellations; keep secrets and PII out of reason.
Execution semantics
Order. Middleware runs in registration order: the
beforehooks first, then the stage operation, then theafterhooks in registration order for every middleware whosecanHandleis true.Short-circuit. The first middleware returning
Interruptfrombeforewins and becomes the cancellation identity: later middleware is not evaluated, the stage operation does not run (Publish: not broadcast; Callback: request not delivered; Execute: handler not invoked), andafteris not called for any middleware for that operation.Surfacing.
fire,exec, andfireCallbackthrowCancelErrorsynchronously at the call site — catch it where cancellation is expected.
Behavioral matrix
Hook | Called when | Can cancel? | Runs on cancellation? |
|---|---|---|---|
| Every operation, before anything else | No | Yes — it is the filter |
|
| Yes ( | Yes — it is where |
|
| No | No |
| Middleware removal or bus disposal | No | Not operation-level — lifecycle-level |
Practical corollary: a logging middleware placed after a guard will not see cancelled attempts; place logging middleware before guards when cancelled attempts must be recorded. For ready-made middleware patterns see Middleware recipes.