Reference · Requests and pages

respond

signature
respond(int, any=, map | null=) -> response

What it does

A response with exactly the status, body and headers given. A route returns it when the plain forms (html, a str, a map) are not enough: a status of its own, a header such as content-type or cache-control, a 204 with nothing. The body is sent as a plain return value would be (html as HTML, a str as text, a map or list as JSON, null as nothing); header names are made lower case and values become text, but a null one, which means no such header. The status must be 200 to 599: a 1xx is an interim answer, after which the client waits for the real one, so it is refused. The value's fields are status, body and headers.

Examples

let r = respond(201, { id: 7 }, { location: "/items/7" })print(r)print(r.status, r.body, r.headers)print(respond(204).status, respond(204).body)
output
<response 201>201 { id: 7 } { location: "/items/7" }204 null
in a program
route GET /api/stats = respond(200, site_stats(), { "cache-control": "public, max-age=60" })route GET /export.csv = respond(200, csv_text(), {    "content-type": "text/csv; charset=utf-8",    "content-disposition": "attachment; filename=\"export.csv\"",})route POST /items { json: { name: str } } {    let id = add_item(name)    respond(201, { id }, { location: `/items/${id}` })}

Edge cases

print(respond(200, "x", { "X-Count": 42, "X-None": null }).headers)print(respond(200).headers)print(respond(200, <p>hi</p>).body)print(respond(200, "x", { "set-cookie": ["a=1", "b=2"] }).headers)
output
{ "x-count": "42", "x-none": null }{}<p>hi</p>{ "set-cookie": ["a=1", "b=2"] }
in a program
fn open_for_business() {    if env("MAINTENANCE") == "1" { reply 503 respond(503, "Back in a minute", { "retry-after": "60" }) }}route GET /checkout { open_for_business(); <CheckoutPage/> }

Errors

A status outside 200 to 599 is a runtime error, and quillo check refuses a 1xx written in the call. So is a header whose name has anything but letters, digits and -, or whose value has a line break: text from a request cannot add headers, or a whole response, of its own. Headers that are not a map, a header's list or map (but a set-cookie list), a location that runs code or carries a page, or a status that is not an int, are runtime errors too. None of these is an error value.

this one fails
print(respond(600, "x"))
output
line 1: `respond` status must be 200-599, got 600
this one fails
print(respond(103, "", { link: "</app.css>; rel=preload; as=style" }))
output
line 1: `respond` status must be 200-599, got 103: a 1xx is an interim answer, and the client would wait for the real one
this one fails
print(respond(200, "x", { "x-note": "a\r\nb" }))
output
line 1: `respond` header `x-note`: names are letters, digits and -, values cannot contain line breaks
this one fails
print(respond(200, "x", { "x-tags": ["a", "b"] }))
output
line 1: `respond` header `x-tags` is a str, got list: only `set-cookie` takes a list, one header an item; join the values with ", "

Chaining

In a pipeline the status would come first, which is rarely what is wanted; respond usually ends a route or a pipeline stage instead, taking the value computed before it.

in a program
route GET /api/me = request | api.key | (r) => respond(200, { ip: r.ip, user: session().user }, { "cache-control": "no-store" })
let found = [1, 2, 3] | filter((n) => n > 5)print((len(found) == 0 ? respond(404, { error: "none" }) : respond(200, found)).status)
output
404

See also

redirect, stream, events, file, set_cookie

Thread
7Useful? Like it, or add to its thread below.

Thread 0 posts

On respond(): questions, tips, corrections, and code that uses it.

No posts yet. The first one opens the thread.

    Edit this page on GitHub · every example's output was made by running it (tools/refcheck.mjs) · questions on Discord or r/quillo