Request context
Handlers and middlewares receive one argument: the context of the request, ctx. Destructure what you need:
What it holds
req and res are the same on every adapter: a handler never touches the native request or response. It returns its value, and sets the status, headers and cookies on res.
req.signal is aborted when the client disconnects: pass it to long operations (fetch(url, { signal: req.signal })).
Keys added by plugins
Plugins add their own keys to the context, typed:
Keys provided with decorateContext() are computed on first access, at most once per request: a route that does not use the mailer does not pay for it.
Using the key of a plugin that is not installed throws an explicit error, rather than returning undefined:
Adding your own keys
The context is extended with TypeScript module augmentation. A plugin provides the value, as in this plugin that exposes the services of the app:
A middleware can also set a key for the request, such as the tenant of a multi-tenant API. Declare it optional, and let a typed middleware guarantee it to the handlers.
See Project structure for the pattern in a complete app.