Skip to content

Context

Every handler and middleware in GamanJS receives a ctx (Context) object containing all request information and utilities for accessing data and sending responses.

URL pathname (without query string):

// Request: GET /users/123?active=true
ctx.path; // '/users/123'

Full URL instance:

ctx.url.origin; // 'http://localhost:3431'
ctx.url.pathname; // '/users/123'
ctx.url.search; // '?active=true'

Raw request information:

ctx.request.id; // Unique request ID (auto-generated)
ctx.request.method; // 'GET', 'POST', etc
ctx.request.url; // Full URL as string
ctx.request.pathname; // Pathname
ctx.request.body(); // Promise<Buffer> — raw body

Get a single route parameter:

// Route: /users/:id
r.get('/users/:id', (ctx) => {
const id = ctx.param('id'); // '123'
return ctx.send({ id }).ok();
});

All route parameters as an object:

// Route: /posts/:postId/comments/:commentId
ctx.params; // { postId: '1', commentId: '42' }

Access query parameters directly:

// Request: GET /search?q=gaman&page=2
ctx.query.q; // 'gaman'
ctx.query.page; // '2'

For parameters with multiple values:

// Request: GET /filter?tag=js&tag=ts
ctx.query.tag; // ['js', 'ts']

Parse body as JSON:

async Create(ctx) {
const body = await ctx.json<{ name: string; email: string }>();
// body.name, body.email
return ctx.send(body).created();
}

Read body as plain text:

async Webhook(ctx) {
const raw = await ctx.text();
return ctx.send({ message: 'OK' }).ok();
}

Parse body as FormData (supports multipart/form-data and application/x-www-form-urlencoded).

Get a single string value from form data:

const email = await ctx.input('email'); // string | null

Get multiple string values from form data:

const tags = await ctx.inputs('tags'); // string[]

Get a single file from form data:

const avatar = await ctx.file('avatar'); // GFile | null

Get multiple files from form data:

const images = await ctx.files('images'); // GFile[]

Get a specific request header value (case-insensitive):

const token = ctx.header('Authorization'); // string | null

GamanHeader instance for reading and manipulating headers:

// Read
ctx.headers.get('Content-Type');
// Set response header
ctx.headers.set('X-Custom-Header', 'value');

Bun’s CookieMap instance for accessing and setting cookies:

// Read
const session = ctx.cookies.get('session_id');
// Set
ctx.cookies.set('session_id', 'abc-123', { httpOnly: true });

Middleware and handlers can share data via the context store:

ctx.set('user', { id: 1, name: 'Angga' });
const user = ctx.get('user');

The primary way to send responses. Returns a GamanResponseBuilder.

return ctx.send({ success: true }).ok();

export default (userService) => ({
async CreatePost(ctx) {
// Route params
const userId = ctx.param('userId');
// Query
const draft = ctx.query.draft === 'true';
// Body
const body = await ctx.json<{ title: string }>();
// Headers
const token = ctx.header('Authorization');
// Set response header
ctx.headers.set('X-Processed-By', 'GamanJS');
// Data from middleware
const currentUser = ctx.get('user');
return ctx.send({
userId,
draft,
title: body.title,
author: currentUser.name,
}).created();
},
});