Postboy Help

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 before to 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; before and after may 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 canHandle returned 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,

    • after is 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:

    • canHandle returned true, and

    • the 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 context as read-only.

  • The message instance is the same object that will be delivered/executed if the operation proceeds.

MiddlewareStage

Enum values

  • MiddlewareStage.Publish

  • MiddlewareStage.Callback

  • MiddlewareStage.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 canHandle to avoid running middleware unnecessarily.

MiddlewareDecision

Shape

  • MiddlewareDecision is an object with at least:

Field

Type

Required

Description

type

MiddlewareDecisionType

yes

Continue or Interrupt

MiddlewareDecisionType enum values

  • MiddlewareDecisionType.Continue

  • MiddlewareDecisionType.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:

    1. build context

    2. call canHandle

    3. if true → call before

    4. if not interrupted → proceed

  • On successful completion of the stage:

    • iterate again in registration order and call after for those where canHandle is 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 middleware

    • clears 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]

29 июня 2026