Documentation
Responses
Kynetra FX handlers return a standard Response. The ctx object provides convenience helpers for the most common cases — json, text, html, redirect, stream, and response — but you can always return a raw new Response().
JSON#
ctx.json(data, init?) serialises any value to JSON, sets Content-Type: application/json, and returns a Response.
app.get('/users', (ctx) => { return ctx.json([{ id: '1', name: 'Alice' }])}) // With a custom status codeapp.post('/users', async (ctx) => { const body = await ctx.jsonBody() return ctx.json({ created: true, ...body }, { status: 201 })})Text#
ctx.text(s, init?) returns a plain-text response with Content-Type: text/plain;charset=UTF-8.
app.get('/health', (ctx) => ctx.text('ok')) app.get('/ping', (ctx) => ctx.text('pong', { status: 200 }))HTML#
ctx.html(s, init?) returns an HTML response with Content-Type: text/html;charset=UTF-8.
app.get('/', (ctx) => ctx.html('<html><body><h1>Hello</h1></body></html>')) // Useful with a template functionfunction template(title: string, body: string) { return '<html><head><title>' + title + '</title></head><body>' + body + '</body></html>'} app.get('/about', (ctx) => ctx.html(template('About', '<p>About us</p>')))Redirects#
ctx.redirect(url, status?) returns a redirect response. The default status is 302 (Found). Pass 301 for a permanent redirect.
app.get('/old-path', (ctx) => ctx.redirect('/new-path') // 302 temporary) app.get('/legacy', (ctx) => ctx.redirect('https://new.example.com', 301) // 301 permanent)Streaming#
ctx.stream(body, init?) wraps a ReadableStream in a Response. Use it for server-sent events, large file transfers, or any progressively-generated content.
app.get('/events', (ctx) => { const { readable, writable } = new TransformStream() const writer = writable.getWriter() const encoder = new TextEncoder() // Write data asynchronously ;(async () => { for (let i = 0; i < 5; i++) { await writer.write(encoder.encode('data: ' + i + ' ')) await new Promise(r => setTimeout(r, 500)) } await writer.close() })() return ctx.stream(readable, { headers: { 'Content-Type': 'text/event-stream' }, })})Raw response#
ctx.response(body?, init?) constructs a raw Response with full control. Equivalent to new Response(body, init) but consistent with the ctx API.
app.get('/no-content', (ctx) => ctx.response(null, { status: 204 })) app.get('/binary', async (ctx) => { const bytes = new Uint8Array([0x89, 0x50, 0x4e, 0x47]) return ctx.response(bytes, { headers: { 'Content-Type': 'image/png' }, })})Returning a native Response#
You can return a plain new Response() from any handler. Kynetra FX will pass it through as-is. This is useful when integrating with other libraries that already return a Response.
app.get('/pass-through', async (ctx) => { // Fetch from an upstream API and return its response directly return fetch('https://api.upstream.com/data')})Setting status codes#
Pass a status in the init object to any helper, or use ctx.status(code) which is chainable:
// Via init optionapp.post('/items', async (ctx) => { return ctx.json({ created: true }, { status: 201 })}) // Via chainable ctx.status()app.delete('/items/:id', (ctx) => { // delete logic... return ctx.status(204).response()})Setting response headers#
ctx.set(name, value) sets a response header. ctx.append(name, value) appends to an existing header. Both must be called before returning the response.
app.get('/cached', (ctx) => { ctx.set('Cache-Control', 'public, max-age=3600') ctx.set('X-Custom-Header', 'hello') return ctx.json({ data: 'cacheable' })}) // Append to an existing header (e.g. Vary)app.use(async (ctx, next) => { const res = await next() ctx.append('Vary', 'Accept-Encoding') return res})Note
ctx.set() and ctx.append() set response headers. To read request headers, use ctx.header(name).Response helper reference#
| Name | Type | Description |
|---|---|---|
| json(data, init?) | Response | Serialize data to JSON with Content-Type: application/json. |
| text(s, init?) | Response | Return a plain-text response. |
| html(s, init?) | Response | Return an HTML response. |
| redirect(url, status?) | Response | Redirect to url. Defaults to 302. |
| stream(body, init?) | Response | Return a streaming response from a ReadableStream. |
| response(body?, init?) | Response | Construct a raw Response with full control. |
| status(code) | ctx | Set the default status code. Chainable — call before a response helper. |
| set(name, value) | void | Set a response header. Call before returning. |
| append(name, value) | void | Append to a response header. Call before returning. |