Stone.jsDocs
Paradigm

Middleware

Terminating & response middleware

Because a middleware wraps next, it owns both sides of the request: before, on the way in, and after, on the way out. The way out is where you shape the response, add headers, and run work that should happen once the outcome is known.

#Acting on the response

Await next(event) to get the response the handler (and inner middleware) produced, then modify or wrap it before returning. This is how envelopes, timing headers and response-wide transforms are done, in one place, for many routes.

app/middleware/SecurityHeaders.tsts
export const securityHeaders = defineMiddleware(async (event, next) => {
  const response = await next(event)              // wait for the outcome
  response.setHeader('X-Content-Type-Options', 'nosniff')
  response.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin')
  return response                                 // hand the shaped response back out
})
The way in guards the request. The way out finishes the response.

#Cleanup after the response

Work that must run whether or not the handler threw belongs in a finally around next: close a span, release a lease, record a metric. It runs on success and on error alike.

app/middleware/Trace.tsts
export const trace = defineMiddleware(async (event, next) => {
  const span = startSpan(event.get('path'))
  try {
    return await next(event)
  } finally {
    span.end()                                    // always runs, success or failure
  }
})

Stone.js

Your app exists in every runtime. Until you run it.

An open-source project by Stone Foundation
Created by Mr. Stone (Evens Pierre)