Skip to main content

Request & Response Primitives

Zelt provides functional primitives for accessing request data and building responses. These primitives can be used as default parameters in controller methods.

Request Primitives

Query Parameters

import { Controller, Get, queryParam, queryParams, response } from '@zeltjs/core';

@Controller('/search')
export class SearchController {
@Get('/')
search(
q = queryParam('q'),
tags = queryParams('tag'),
res = response(),
) {
// q: string | undefined
// tags: string[] (empty array if not provided)
return res.json({ query: q, tags });
}
}
FunctionReturn TypeDescription
queryParam(name)string | undefinedGet a single query parameter
queryParams(name)string[]Get all values for a query parameter

Headers

import { Controller, Get, header, response } from '@zeltjs/core';

@Controller('/api')
export class ApiController {
@Get('/info')
info(
userAgent = header('User-Agent'),
acceptLanguage = header('Accept-Language'),
res = response(),
) {
return res.json({ userAgent, acceptLanguage });
}
}
FunctionReturn TypeDescription
header(name)string | undefinedGet a request header value

Cookies

import { Controller, Get, cookie, response } from '@zeltjs/core';

@Controller('/session')
export class SessionController {
@Get('/')
getSession(
sessionId = cookie('session_id'),
res = response(),
) {
return res.json({ sessionId });
}
}
FunctionReturn TypeDescription
cookie(name)string | undefinedGet a cookie value

URL & Path

import { Controller, Get, url, path, method, response } from '@zeltjs/core';

@Controller('/debug')
export class DebugController {
@Get('/request')
requestInfo(
fullUrl = url(),
requestPath = path(),
httpMethod = method(),
res = response(),
) {
return res.json({
url: fullUrl, // "http://localhost:3000/debug/request?foo=bar"
path: requestPath, // "/debug/request"
method: httpMethod // "GET"
});
}
}
FunctionReturn TypeDescription
url()stringFull request URL including query string
path()stringRequest path without query string
method()stringHTTP method (GET, POST, etc.)

Request Body

import { Controller, Post, body, response } from '@zeltjs/core';

@Controller('/upload')
export class UploadController {
@Post('/text')
async uploadText(res = response()) {
const text = await body('text');
return res.json({ received: text });
}

@Post('/json')
async uploadJson(res = response()) {
const data = await body('json');
return res.json({ received: data });
}

@Post('/form')
async uploadForm(res = response()) {
const formData = await body('form');
return res.json({ fields: Object.fromEntries(formData) });
}
}
TypeReturn TypeDescription
body('text')Promise<string>Raw text body
body('json')Promise<unknown>Parsed JSON body
body('form')Promise<FormData>Form data (multipart or urlencoded)
body('arrayBuffer')Promise<ArrayBuffer>Raw binary data
body('blob')Promise<Blob>Blob data
tip

For validated request bodies with automatic type inference, use validated() instead.

Path Parameters

import { Controller, Get, pathParam, response } from '@zeltjs/core';

@Controller('/users')
export class UserController {
@Get('/:id')
getUser(
id = pathParam('id'),
res = response(),
) {
// id: string (throws if not defined)
return res.json({ userId: id });
}
}
FunctionReturn TypeDescription
pathParam(name)stringGet a path parameter (throws if undefined)

Response Primitives

response()

The response() primitive returns a builder for constructing HTTP responses:

import { Controller, Get, Post, response } from '@zeltjs/core';

@Controller('/api')
export class ApiController {
@Get('/data')
getData(res = response()) {
return res.json({ message: 'Hello' });
}

@Get('/redirect')
redirect(res = response()) {
return res.redirect('/new-location', 302);
}

@Get('/text')
getText(res = response()) {
return res.text('Plain text response');
}

@Post('/created')
create(res = response()) {
return res.json({ id: '123' }, 201);
}
}

Response Methods

MethodDescription
json(data, status?, headers?)JSON response with optional status code and headers
text(data, status?)Plain text response
redirect(url, status?)HTTP redirect (default: 302)
body(data, status?)Raw body response
header(name, value)Set a response header (chainable)

Setting Cookies

import { Controller, Post, response } from '@zeltjs/core';

@Controller('/auth')
export class AuthController {
@Post('/login')
login(res = response()) {
return res
.setCookie('session_id', 'abc123', {
httpOnly: true,
secure: true,
sameSite: 'Strict',
maxAge: 60 * 60 * 24, // 1 day
})
.json({ success: true });
}

@Post('/logout')
logout(res = response()) {
return res
.deleteCookie('session_id')
.json({ success: true });
}
}
OptionTypeDescription
domainstringCookie domain
expiresDateExpiration date
httpOnlybooleanHTTP-only flag
maxAgenumberMax age in seconds
pathstringCookie path
securebooleanSecure flag
sameSite'Strict' | 'Lax' | 'None'SameSite attribute

Chaining Response Methods

Response methods that modify state (header, setCookie, deleteCookie) return the builder, allowing method chaining:

@Get('/download')
download(res = response()) {
return res
.header('Content-Disposition', 'attachment; filename="report.csv"')
.header('Cache-Control', 'no-cache')
.setCookie('download_started', 'true')
.text('id,name\n1,Alice\n2,Bob');
}