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.
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.
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
}
})