Foundations
Middleware & the pipeline
On its way to a handler, every event passes through a pipeline: an ordered chain of steps, each able to inspect the event, pass it inward, and then act on the response coming back. This is the same chain of responsibility that builds the manifest, now applied to requests.
#A pipe, in and out
The principle
Cross-cutting concerns, auth, validation, logging, timing, do not belong inside your business logic, but they do belong on the path to it. A pipeline gives each concern a place on that path, with control over what continues and what comes back.
In Stone.js
A Stone.js middleware is a pipe: it receives the event and a next function. Call next(event) to continue toward the handler; what you do before is the way in, what you do with its result is the way out. Return early to short-circuit.
import { Middleware, NextPipe } from '@stone-js/core'
import { IncomingHttpEvent, OutgoingHttpResponse } from '@stone-js/http-core'
@Middleware()
export class Timing {
async handle (event: IncomingHttpEvent, next: NextPipe<IncomingHttpEvent, OutgoingHttpResponse>) {
const started = performance.now()
const response = await next(event) // pass control inward
response.setHeader('x-time', String(performance.now() - started))
return response // ...then act on the way out
}
}import { defineMiddleware } from '@stone-js/core'
export const timing = defineMiddleware(async (event, next) => {
const started = performance.now()
const response = await next(event) // pass control inward
response.setHeader('x-time', String(performance.now() - started))
return response // ...then act on the way out
})Everything before next() is the way in. Everything after is the way out. Skip next() and the request stops here.
#Where middleware attaches
- Globally: on the Blueprint (
stone.middleware), for every event. - Per route or handler: in the route's
middlewareoption, for just those intentions.
Auth, authorization and validation from the Build section are all just middleware: requireAuth(), authorize(...) and validate(...) return pipes that sit on the path to your method.