Migrating Middleware from 3.4
Postboy 3.5 replaces the 3.4 single-hook middleware with a staged abstract class, moves chain management to infrastructure messages, and turns throw-to-block into a structured cancellation. This guide maps every 3.4 construct to its 3.5 equivalent. All changes are source-breaking: middleware written for 3.4 does not compile against 3.5.
What changed
3.4 | 3.5 |
|---|---|
| abstract class with |
One | Stage-aware hooks: |
|
|
|
|
Throwing from | Return |
No visibility into outcomes |
|
No filter — every middleware saw every message |
|
postboy.addMiddleware and postboy.removeMiddleware were removed in 3.5 together with lock, unlock, addNamespace, eliminateNamespace, and unregister — infrastructure messages are the only way to mutate the bus.
Rewrite the middleware
A 3.4 implementation with a single hook:
Split the hook by responsibility: gating goes to before, observation to after, filtering to canHandle:
Replace throw-to-block
Throwing from handle was the only way to stop an operation in 3.4, and callers saw an ordinary exception:
In 3.5 a block is a decision, and the bus converts it into a structured error:
Call sites that expect blocking now catch a CancelError instead of parsing message text:
Migration checklist
Replace every
postboy.addMiddleware(...)/removeMiddleware(...)call withexec(new AddMiddleware(...))/exec(new RemoveMiddleware(...)).Split each
handleimplementation: policy checks intobefore, logging and metrics intoafter.Add a
canHandlefilter — stage first, thenmessage.id. Middleware now also sees infrastructure messages, which are executors on theExecutestage.Give guards an explicit name via
super('ReadonlyGuard'): theCancelErrorreason is generated from it.Implement
dispose()for anything the middleware allocates;RemoveMiddlewareandpostboy.dispose()call it.Assume
aftercan be skipped: any middleware may interrupt the operation first.Update tests: assert on
CancelError.detailsinstead of thrown message strings, and remove middleware between tests to avoid leakage.