Handling requests
Methods, headers, query, JSON bodies, status codes, response limits.
One function, every path under it
A function owns its URL and everything below it. That is what lets one deployment be an application rather than a single endpoint:
https://cloud.flaresinc.com/run/YOUR_PROJECT/api → path "/"
https://cloud.flaresinc.com/run/YOUR_PROJECT/api/users → path "/users"
https://cloud.flaresinc.com/run/YOUR_PROJECT/api/users/123 → path "/users/123"
The path your code sees is the part below your function's own name — not the project id, not the function name. Rename the function and its routing still works.
return function (Request $request): Response {
if (($p = $request->match('/users/{id}')) !== null) {
return Response::json(['user' => $p['id']]);
}
if ($request->route() === 'POST /posts') {
return Response::json(['created' => true], 201);
}
return Response::json(['error' => 'not_found'], 404);
};
| On the request | What it gives you |
|---|---|
$request->path | The path below your function. / at its root. |
$request->segments() | ['users', '123'] — the path split, empties dropped. |
$request->segment(0) | One segment by position, or null past the end. |
$request->match('/users/{id}') | Captured parameters, or null when it does not match. {rest*} takes everything left. |
$request->route() | "POST /posts" — method and path, for a match statement. |
$request->function | Your function's own name, for building links back to itself. |
Methods
The gateway accepts GET, POST, PUT, PATCH and DELETE at the same endpoint; your handler decides:
return function (Request $request): Response {
return match ($request->method) {
'GET' => Response::json(list_items()),
'POST' => Response::json(create_item($request->json() ?? []), 201),
'DELETE' => Response::empty(),
default => Response::json(['error' => 'method_not_allowed'], 405),
};
};
Input
$request->query('page', '1'); // ?page=2
$request->header('X-Signature'); // case-insensitive
$request->body; // raw, exactly as sent
$request->json(); // decoded array, or null
Cookie, Authorization and X-Flares-User-Token are stripped
before your code sees the headers: platform credentials never reach customer code. The verified
identity arrives as $request->user() instead.
Output
return Response::json(['ok' => true], 200, ['X-My-Header' => 'value']);
You control the status and your own headers. The platform owns transport headers —
Set-Cookie, Content-Length, Transfer-Encoding,
Connection — and headers containing CR/LF are dropped, so a header cannot be
injected through a value.
CORS
Responses carry Access-Control-Allow-Origin: * and allow the common methods and
headers, so a browser on your own domain can call a function directly. Authorization is the
token's job, not the origin's.
Request ids
Every response carries X-Flares-Request-Id. Log it client-side and you can find the
exact invocation in Logs — it is also the
id that guarantees an internal retry cannot double-bill you.
Errors
If your code throws or dies, the caller gets 500 with
{"error":"function_error","request_id":"…"} — never your stack trace, which could
carry paths or secrets. The full error and any output are in your logs.