Documentation / @zerotal/core / index / HttpContext
Class: HttpContext<TParams>
Defined in: pipeline/HttpContext.ts:66
The central per-request object, exposing request input, response helpers, route-model bindings, session flash, and after-response hooks to controllers and middleware.
Lives in the AsyncLocalStorage store AND travels through the pipeline. Both are the same object reference — no sync needed between them.
Examples
// A controller action reading input and returning JSON:
async show(ctx: HttpContext) {
const id = ctx.integer('id');
const post = ctx.model<Post>('post');
return ctx.json({ id, post });
}
// An inline route handler — the context is passed directly:
Router.post('/subscribe', async (ctx) => {
const { email } = await ctx.body<{ email: string }>();
ctx.flash('success', `Subscribed ${email}`);
ctx.redirect('/thanks', 303);
});
Type Parameters
TParams
TParams extends Record<string, unknown> = Record<string, string>
Shape of ctx.params (route params plus resolved model
bindings). Defaults to a string-keyed record.
Constructors
Constructor
new HttpContext<
TParams>(request,container):HttpContext<TParams>
Defined in: pipeline/HttpContext.ts:129
Parameters
request
Request
container
Returns
HttpContext<TParams>
Files & uploads
file()
file(
field):Promise<UploadedFile|null>
Defined in: pipeline/HttpContext.ts:638
Return the first uploaded file for the given form field, or null if absent.
Parses and caches the multipart body on first call.
Parameters
field
string
Returns
Promise<UploadedFile | null>
Example
const avatar = await ctx.file('avatar');
if (!avatar?.isValid({ maxSize: 2 * 1024 * 1024, mimes: ['image/jpeg', 'image/png'] })) {
return redirect().back().withErrors({ avatar: 'Invalid file.' });
}
const path = await avatar.store('avatars', Storage.disk());
files()
files(
field):Promise<UploadedFile[]>
Defined in: pipeline/HttpContext.ts:657
Return all uploaded files for the given form field.
Useful for <input type="file" multiple> inputs.
Parameters
field
string
Returns
Promise<UploadedFile[]>
Example
const attachments = await ctx.files('attachments');
for (const file of attachments) {
await file.store('attachments', Storage.disk('s3'));
}
Lifecycle
took
Get Signature
get took():
number
Defined in: pipeline/HttpContext.ts:153
Elapsed milliseconds since this request started.
Returns
number
afterResponse()
afterResponse(
callback):this
Defined in: pipeline/HttpContext.ts:703
Register a callback to fire after the Response is sent to the client. Calls container.acquire() synchronously at registration time — before any await — so the request's finally block cannot flush the scope before the callback has a chance to run. This ordering fixes a scope-flush race.
Parameters
callback
() => Promise<void>
Returns
this
Example
ctx.afterResponse(async () => {
await Analytics.track('page_view', { path: ctx.path() });
});
onResponseReady()
onResponseReady(
callback):this
Defined in: pipeline/HttpContext.ts:744
Register a callback that runs once the final Response exists, before it is
returned to the client — the last point at which a header can still be set.
This is what a middleware needs when its work has to land on every
response, including one produced by the exception handler. A middleware's own
finally block cannot do that: when a handler throws, the pipeline unwinds
before any response has been built, so there is nothing to write to. Sessions
are the motivating case — a Set-Cookie that only appears on the success path
silently drops flashed validation errors on the redirect that carries them.
Finalizers run in registration order and are awaited. An error thrown by one is logged and swallowed, because a failed finalizer must not turn a rendered response into a crash.
Parameters
callback
(response) => Promise<void>
Returns
this
Example
ctx.onResponseReady(async (response) => {
response.headers.set('X-Request-Id', ctx.requestId);
});
fake()
staticfake(url?,init?,container?):HttpContext
Defined in: pipeline/HttpContext.ts:801
Create a fake HttpContext for unit tests. Does not require a running server.
Parameters
url?
string = "http://localhost/"
init?
RequestInit = {}
container?
Returns
HttpContext
Example
const ctx = HttpContext.fake('http://localhost/posts?page=2');
expect(ctx.integer('page')).toBe(2);
tryGet()
statictryGet():HttpContext<Record<string,string>> |undefined
Defined in: pipeline/HttpContext.ts:821
The current request's HttpContext, or undefined outside a request.
Safe in code that runs both in and out of requests (CLI commands, queue
workers, scheduled jobs).
Returns
HttpContext<Record<string, string>> | undefined
Other
requestId
readonlyrequestId:string
Defined in: pipeline/HttpContext.ts:67
startedAt
readonlystartedAt:number
Defined in: pipeline/HttpContext.ts:68
url
readonlyurl:URL
Defined in: pipeline/HttpContext.ts:69
params
params:
TParams
Defined in: pipeline/HttpContext.ts:74
sessionId?
optionalsessionId?:string
Defined in: pipeline/HttpContext.ts:76
session?
optionalsession?:SessionContract
Defined in: pipeline/HttpContext.ts:82
_routeDef?
optional_routeDef?:object
Defined in: pipeline/HttpContext.ts:85
pattern
pattern:
string
controller
controller:
string
action
action:
string
_transaction?
optional_transaction?:TransactionContext
Defined in: pipeline/HttpContext.ts:90
locale
locale:
string="en"
Defined in: pipeline/HttpContext.ts:93
response
response:
Response|undefined=undefined
Defined in: pipeline/HttpContext.ts:96
Set by controllers/route handlers. Read by Application after pipeline runs.
_afterResponseCallbacks
_afterResponseCallbacks: () =>
Promise<void>[] =[]
Defined in: pipeline/HttpContext.ts:99
Returns
Promise<void>
_responseFinalizers
_responseFinalizers: (
response) =>Promise<void>[] =[]
Defined in: pipeline/HttpContext.ts:104
Parameters
response
Response
Returns
Promise<void>
_server
_server:
RequestIPProvider|undefined=undefined
Defined in: pipeline/HttpContext.ts:109
_models
readonly_models:Map<string,unknown>
Defined in: pipeline/HttpContext.ts:113
request
readonlyrequest:Request
Defined in: pipeline/HttpContext.ts:130
container
readonlycontainer:ScopedResolver
Defined in: pipeline/HttpContext.ts:131
Redirects
redirect()
redirect(
url,status?):void
Defined in: pipeline/HttpContext.ts:283
Set an HTTP redirect response. Default 302 (Found). Use 303 (See Other) after POST/PUT/DELETE — Inertia and browsers always issue a GET on a 303, preventing form re-submission.
Parameters
url
string
status?
301 | 302 | 303 | 307 | 308
Returns
void
Example
ctx.redirect('/dashboard'); // 302
ctx.redirect('/dashboard', 303); // 303 after POST
back()
back(
status?):void
Defined in: pipeline/HttpContext.ts:301
Redirect back to the previous page using the Referer header. Falls back to '/' when no Referer is present or when the Referer points to a different origin (prevents open-redirect attacks).
Parameters
status?
301 | 302 | 303 | 307 | 308
Returns
void
Example
ctx.back(); // 302 to Referer
ctx.back(303); // 303 to Referer (use after Inertia POST)
Request data
path()
path():
string
Defined in: pipeline/HttpContext.ts:345
The current request pathname (no query string).
Returns
string
fullUrl()
fullUrl():
string
Defined in: pipeline/HttpContext.ts:354
The full request URL including query string.
Returns
string
host()
host():
string
Defined in: pipeline/HttpContext.ts:363
The host portion of the URL (hostname + port if non-standard).
Returns
string
subdomains
Get Signature
get subdomains():
Record<string,string>
Defined in: pipeline/HttpContext.ts:377
Subdomain params captured from a Router.group({ domain }) match.
Example
// Router.group({ domain: ':tenant.app.com' }, () => { ... });
ctx.subdomains; // { tenant: 'acme' } for acme.app.com
ctx.subdomain('tenant'); // 'acme'
Returns
Record<string, string>
subdomain()
subdomain(
name):string|null
Defined in: pipeline/HttpContext.ts:386
A single subdomain param, or null when absent.
Parameters
name
string
Returns
string | null
is()
is(
pattern):boolean
Defined in: pipeline/HttpContext.ts:401
Test the request path against a glob-style pattern.
* matches any sequence of characters except /.
** matches any sequence including /.
Parameters
pattern
string
Returns
boolean
Example
ctx.is('/admin/*') // true for /admin/users, false for /posts
ctx.is('/posts/**') // true for /posts/1/comments
ip()
ip():
string|null
Defined in: pipeline/HttpContext.ts:427
The raw client IP address taken directly from the TCP socket.
Available when running inside Bun.serve() — returns null in tests
or any context where the Bun server reference was not injected.
When Bun sits behind a reverse proxy (nginx, Caddy, etc.) this returns
the proxy's IP, not the end-user's. Use ThrottleMiddleware's
trustedProxies option together with X-Forwarded-For to resolve the
real client IP in those deployments.
Returns
string | null
model()
model<
T>(name):T
Defined in: pipeline/HttpContext.ts:451
Retrieve a route-model-bound instance by its parameter name.
The instance is resolved automatically by the framework before the controller
runs, using the model bound to the param — implicitly by name, or with .bind() on the
route. Throws if no binding was resolved for the given param name (which means
either the route has no such param or no binding was registered).
Type Parameters
T
T = unknown
Parameters
name
string
Returns
T
Example
// Route: Router.get('/users/:user', UserController, 'show')
async show(ctx: HttpContext) {
const user = ctx.model<User>('user');
return ctx.json({ user });
}
Throws
when no binding was resolved for name (the route has no
such param, or nothing bound it).
header()
header(
key,fallback?):string|null
Defined in: pipeline/HttpContext.ts:469
Retrieve a request header by name (case-insensitive).
Returns fallback (default null) when the header is absent.
Parameters
key
string
fallback?
string | null
Returns
string | null
bearerToken()
bearerToken():
string|null
Defined in: pipeline/HttpContext.ts:479
Extract the Bearer token from the Authorization header.
Returns null when absent or the header does not use the Bearer scheme.
Returns
string | null
isJson()
isJson():
boolean
Defined in: pipeline/HttpContext.ts:491
True when the request sends a JSON body (Content-Type: application/json).
Returns
boolean
wantsJson()
wantsJson():
boolean
Defined in: pipeline/HttpContext.ts:501
True when the client expects a JSON response (Accept: application/json).
Useful in exception handlers to decide between an error page and a JSON error.
Returns
boolean
query()
query(
key,fallback?):string|undefined
Defined in: pipeline/HttpContext.ts:517
Read a URL query-string parameter by name.
Returns fallback (default undefined) when the param is absent.
Parameters
key
string
fallback?
string
Returns
string | undefined
Example
const page = ctx.query('page', '1');
const q = ctx.query('search');
integer()
integer(
key,fallback?):number|undefined
Defined in: pipeline/HttpContext.ts:532
Parse a query param or route param as an integer.
Checks route params first, then the query string.
Returns fallback when the value is absent or not a valid integer.
Parameters
key
string
fallback?
number
Returns
number | undefined
Example
const id = ctx.integer('id'); // route param
const page = ctx.integer('page', 1); // query string with default
string()
string(
key,fallback?):string|undefined
Defined in: pipeline/HttpContext.ts:549
Read a query param or route param as a string. Checks route params first, then the query string.
Parameters
key
string
fallback?
string
Returns
string | undefined
Example
const slug = ctx.string('slug');
const sort = ctx.string('sort', 'asc');
boolean()
boolean(
key,fallback?):boolean
Defined in: pipeline/HttpContext.ts:562
Read a query param or route param coerced to a boolean.
Truthy values: '1', 'true', 'yes', 'on' (case-insensitive).
Parameters
key
string
fallback?
boolean = false
Returns
boolean
Example
const active = ctx.boolean('active', false);
body()
body<
T>():Promise<T>
Defined in: pipeline/HttpContext.ts:578
Parse and cache the JSON request body.
Subsequent calls return the cached result — safe to call multiple times.
Returns {} when the body is absent or not valid JSON.
Type Parameters
T
T extends Record<string, unknown> = Record<string, unknown>
Returns
Promise<T>
Example
const { title, body } = await ctx.body<{ title: string; body: string }>();
input()
input<
T>(key,fallback?):T
Defined in: pipeline/HttpContext.ts:680
Read a value from the merged input bag in priority order: route params → cached JSON body → query string.
Body data is only available here if ctx.body() was awaited earlier in
the lifecycle (e.g. by a FormRequest or validate() call). For guaranteed
body access, use await ctx.body() or a FormRequest.
Type Parameters
T
T = unknown
Parameters
key
string
fallback?
T
Returns
T
Example
ctx.input('id') // route param :id or query ?id=
ctx.input('q', 'all') // with fallback
Responses
json()
json(
data,status?):void
Defined in: pipeline/HttpContext.ts:168
Set a JSON response.
Parameters
data
unknown
status?
number = 200
Returns
void
Example
ctx.json({ user }); // 200
ctx.json({ errors }, 422); // 422
view()
Call Signature
view(
markup,status?):void
Defined in: pipeline/HttpContext.ts:196
Respond with a server-side view rendered to a full HTML document.
Prepends <!DOCTYPE html> and sets Content-Type: text/html.
Accepts either pre-rendered markup, or a view component plus its props.
A view component receives the request HttpContext (route params and
model bindings live on ctx.params) and the props you pass as a second
argument. Pair with core's JSX runtime (add /** @jsxImportSource @zerotal/core */
to view files) so JSX evaluates directly to HTML.
Parameters
markup
ViewMarkup
status?
number
Returns
void
Example
// resources/views/Welcome.tsx
export default function Welcome(ctx: HttpContext, { title }: { title: string }) {
return <html><body><h1>{title}</h1><p>{ctx.url.pathname}</p></body></html>;
}
// In a route/controller:
ctx.view(Welcome, { title: 'Hello' });
// Or pass already-rendered markup:
ctx.view(Welcome(ctx, { title: 'Hello' }));
Call Signature
view<
P>(component,props?,status?):void|Promise<void>
Defined in: pipeline/HttpContext.ts:197
Respond with a server-side view rendered to a full HTML document.
Prepends <!DOCTYPE html> and sets Content-Type: text/html.
Accepts either pre-rendered markup, or a view component plus its props.
A view component receives the request HttpContext (route params and
model bindings live on ctx.params) and the props you pass as a second
argument. Pair with core's JSX runtime (add /** @jsxImportSource @zerotal/core */
to view files) so JSX evaluates directly to HTML.
Type Parameters
P
P extends Record<string, unknown> = Record<string, never>
Parameters
component
(ctx, props) => ViewMarkup | Promise<ViewMarkup>
props?
P
status?
number
Returns
void | Promise<void>
Example
// resources/views/Welcome.tsx
export default function Welcome(ctx: HttpContext, { title }: { title: string }) {
return <html><body><h1>{title}</h1><p>{ctx.url.pathname}</p></body></html>;
}
// In a route/controller:
ctx.view(Welcome, { title: 'Hello' });
// Or pass already-rendered markup:
ctx.view(Welcome(ctx, { title: 'Hello' }));
markdown()
markdown(
content,options?,status?):void
Defined in: pipeline/HttpContext.ts:244
Render a Markdown string to a full HTML document using Bun's built-in
Bun.markdown.html(). Automatically enables tables, strikethrough,
tasklists, autolinks, and heading IDs — pass options to override.
Useful for serving .md files as documentation pages:
Parameters
content
string
options?
BunMarkdownOptions & object
status?
number = 200
Returns
void
Example
const content = await Bun.file('./docs/getting-started.md').text();
ctx.markdown(content);
// Custom title / options:
ctx.markdown(content, { title: 'Getting Started', headings: { ids: true } });
html()
html(
markup,status?):void
Defined in: pipeline/HttpContext.ts:265
Respond with a raw HTML string. Unlike view(), no DOCTYPE is prepended —
useful for HTML fragments, partials, or when you manage the document shell
yourself (e.g. when returning a partial for htmx or Turbo Streams).
Parameters
markup
string | { toString: string; }
status?
number = 200
Returns
void
Example
ctx.html('<p>Updated!</p>');
ctx.html(renderPartial(data), 200);
Session & state
flash()
flash(
key,value):void
Defined in: pipeline/HttpContext.ts:320
Write a value into the session for the next request. Requires SessionMiddleware to be active; silently no-ops if absent.
Use flash() to pass data across a redirect (errors, status messages, etc.). Read it back with flashed() on the next request.
Parameters
key
string
value
unknown
Returns
void
Example
ctx.flash('success', 'Post saved!');
ctx.flash('errors', { email: 'Already taken' });
flashed()
flashed<
T>(key):T|undefined
Defined in: pipeline/HttpContext.ts:334
Read a value that was flashed in the previous request. Returns undefined if the key was not flashed or session is absent.
Type Parameters
T
T = unknown
Parameters
key
string
Returns
T | undefined
Example
const errors = ctx.flashed<Record<string, string>>('errors');
const success = ctx.flashed<string>('success');