Request
Capy
handler request : any
Every Capy handler binds request implicitly as an any. You can also declare request : any explicitly. All handlers in a request receive the same object. Application keys written on it remain visible to later handlers.
Read scalars through a converter with a fallback, so a key that is absent has a defined value rather than an error:
var name := string(request.query.name, fallback: "guest")
var page := s64(request.query.page, fallback: 1)
var debug := bool(request.query.debug)Output
No outputUse the ? suffix to test whether a value is not none. A missing key and an existing key containing none both return false. Use has(request.query, "token") when you need key existence:
if request.query.token? { print("token supplied\n") }Output
No outputFields
| Field | Type | Contains |
|---|---|---|
method | string | GET, POST, and so on |
query | map | parsed query-string parameters |
form | map | parsed form body parameters |
params | map | merged query and form parameters. Form values win when keys match. |
body | string | the raw request body |
headers | map | request headers, lowercased with dashes: content-type, x-request-id |
cookies | map | request cookies by name |
files | array | uploaded files, each with field, name, size, temporary_path |
route | map | path, page, raw_path, valid |
url | map | script, base |
server | map | remaining server and CGI variables, original uppercase names |
session | map | session state, updated by session effects |
config | map | request-visible configuration, including start_directory |
connection | map | connection information |
unit | string | entry unit source path |
websocket | map | current connection_id, scope, opcode, binary, connections |
call | map | current dispatch information |
out | map | response status, headers, and cookies |
Form and JSON bodies
request.form contains parsed form fields. JSON fields do not appear in request.form or request.params. Decode a JSON body explicitly:
var input := json_decode(string(request.body)).value
var title := string(input.title, fallback: "Untitled")request.files contains multipart uploads. field is the form field name, and name is the client-supplied filename. temporary_path names the uploaded bytes on the server. Bearer removes temporary uploads after the request. Move a file with file_rename() if you need to keep it.
Headers and server variables
headers holds anything that arrived as an HTTP header, renamed for readability: the transport's HTTP_X_REQUEST_ID appears as request.headers["x-request-id"]. content-type and content-length are included even though they arrive without the HTTP_ prefix. Use bracket syntax for these, since the names contain dashes.
request.config.start_directory is the process start directory. It stays stable when a unit changes its current directory.
server holds everything else — QUERY_STRING, REMOTE_ADDR, SERVER_NAME — under the original uppercase names. method, route, and url are lifted out of server into their own fields, so look for them there rather than in server.
Reading and writing
Bearer reserves call, unit, out, session, websocket, and connection. Bearer does not refresh request keys between handlers. Do not use them for application state. Add application keys such as request.user or request.pagefacts instead.
Set request.out.status, request.out.headers, or request.out.cookies to change the response. Bearer applies request.out once after the top handler finishes. print() appends to the response body.
Components and tasks receive input through a props : any parameter. Components share the caller's props object. Tasks receive a serialized copy in another process.
Exported (any) any functions capture request implicitly. Ordinary helpers that need it declare request : capture any.
print(string(request.query.name, fallback: "guest"), "\n")
Output
guestif string(request.method) == "POST"
{
print("saved ", request.form.answer, "\n")
}
else
{
print("<form method=\"post\"><input name=\"answer\"></form>", "\n")
}
Output
<form method="post"><input name="answer"></form>print(string(request.headers["user-agent"], fallback: "unknown"), "\n")
print(string(request.cookies.session, fallback: "none"), "\n")
Output
unknown
nonefor file := request.files
{
print(file.name, " ", u64(file.size), "\n")
}
Output
No outputif request.query.page?
{
print("page ", s64(request.query.page, fallback: 1), "\n")
}
else
{
print("no page requested\n")
}
Output
no page requested