Request context
The object that describes the request in flight.
Every request gets one RequestContext. Middlewares and error handlers receive it, handlers
get it as ctx, and scoped services can inject it.
| Member | Value |
|---|---|
request | The Fetch Request. |
method, headers | Shortcuts to the request's. |
url | A parsed URL, created on first use. |
query | The query string as an object. Repeated keys become arrays. |
params | Raw route parameters, decoded. |
route | { method, path, name, meta }, or undefined when nothing matched. |
remoteAddress | The peer's IP address from the adapter. Behind a proxy, the proxy's. |
provider | The request's DI scope. |
body() | The parsed body, read once and cached. |
cookies | get, has, all for the request; set, delete for the response. |
setHeader(name, value), responseHeaders | Headers to add to the response. |
set(key, value), get(key) | A per-request state bag. |
See handlers for worked examples of each.
Injecting it
@Service({ lifetime: 'scoped' })
export class CurrentUser {
readonly id: string | undefined;
constructor(ctx: RequestContext) {
this.id = ctx.headers.get('x-user-id') ?? undefined;
}
}
route.get('/me', {
services: { user: CurrentUser },
handle: ({ user }) => ({ id: user.id }),
});Only scoped and transient services can inject the context. A singleton that tries is a captive dependency, and Suku refuses to start.
Sharing state
const authenticate = middleware(async (ctx, next) => {
ctx.set('user', await verify(ctx.headers.get('authorization')));
return next();
});
route.get('/me', { middlewares: [authenticate], handle: ({ ctx }) => ctx.get<User>('user') });The body
A route with a body schema receives the validated body. Without one, body is undefined
and nothing is read. Call ctx.body() to parse it yourself; the result is cached, so a
middleware and a handler share one read.
| Content type | Result |
|---|---|
application/json, *+json | The parsed value. Malformed JSON is a 400. |
application/x-www-form-urlencoded | An object. Repeated keys become arrays. |
multipart/form-data | A FormData. |
text/*, or none | A string. |
| Anything else | A Uint8Array. |
Bodies over the limit get 413. The limit is 1 MiB unless set.
await Suku.create({ features: [AppFeature], bodyLimit: 5 * 1024 * 1024 });