CORE CONCEPTS

Query Parameters

ctx.query gives you access to the request's URL query string. It's both callable and indexable. Pick whichever reads better at the call site.

Reading Query Params

Both access styles work
app.get('/search', async (ctx) => { const page = ctx.query('page'); // callable style const limit = ctx.query.limit; // property style return json({ page, limit }); });

A request to /search?page=2&limit=20 produces page: "2", limit: "20". All values are plain strings. Parse numbers/booleans yourself if needed.

Iterating All Params

Since query values are also set as own properties on the query function, Object.keys() gives you every param name:

List every query param
app.get('/debug', async (ctx) => { const keys = Object.keys(ctx.query); return json({ keys }); });

Lazy Parsing

ctx.query is parsed from the request URL on first access and cached for the rest of the request. If a handler never reads ctx.query, the query string is never parsed at all, a small but deliberate performance detail.

Missing Params

Accessing a param that wasn't provided returns undefined. There's no throwing:

Missing params are undefined
app.get('/items', async (ctx) => { const sort = ctx.query.sort ?? 'created_at'; // fall back to a default return json({ sort }); });
Context Object
Request Utilities