Requests & Responses
Every handler in Fast works with two things: the incoming request and the response it sends back. Both are small, predictable objects, and you will reach for them constantly.
Reading the request
Inside any handler you can grab the current request with the request() helper. It is aware of the current fiber, so concurrent requests never see each other's data. Here is the tour:
$r = request();
$r->method; // "GET"
$r->path; // "/user/42"
$r->query('page', '1'); // a query-string value, with a default
$r->header('accept'); // a header, matched case-insensitively
$r->json(); // the decoded JSON body, or null
$r->form(); // the parsed urlencoded body
$r->attribute('id'); // a route parameter
A couple of things worth knowing. query() and the header lookup both accept a default, so you do not have to null-check everywhere. json() returns null when the body is not valid JSON, rather than throwing.
A note on request bodies
request()->form() parses only application/x-www-form-urlencoded bodies. If you are receiving JSON, use json(). For any other media type, read the raw body and parse it yourself.
Fast does not ship a multipart upload parser, and it does not parse chunked transfer-encoding. Requests are expected to send a valid
Content-Length. This keeps the HTTP layer small and closes off a class of request-smuggling attacks.
Building responses
You have two equivalent ways to build a response: the global helper functions, or the static methods on Response. Use whichever reads better to you.
// Global helpers
return html('<h1>hi</h1>');
return text('plain text');
return json(['ok' => true]);
return redirect('/login');
// The equivalent Response methods
return Response::html('<h1>hi</h1>');
return Response::text('plain text');
return Response::json(['ok' => true]);
return Response::redirect('/login');
Remember the return-value shortcut, too: if you just return a string, Fast wraps it in an HTML response, and if you return an array it becomes JSON. The explicit helpers are for when you want to set a status or headers.
Status codes and headers
Responses are immutable. Methods like withStatus() and withHeader() return a new response rather than mutating the old one, so you chain them:
return json($data)->withStatus(201)->withHeader('X-Id', '7');
Header values are validated the moment you set them. If you try to sneak a CR or LF into a header value, Fast throws an InvalidArgumentException right where you built the response, instead of letting a malformed header reach the wire. Interior spaces are fine, so something like Cache-Control: public, max-age=0 works exactly as you would expect.
Returning specific error statuses
When you need to bail out with a particular status code, throw an HttpException from anywhere in your code and the kernel turns it into a proper response instead of a generic 500:
use Fast\Http\HttpException;
if ($missing) {
throw new HttpException(404, 'Not found');
}
You can pass an optional payload and headers to the exception too, which is handy for APIs that want a structured error body.
Now that you can read requests and shape responses, let us render some HTML with Views & Templates.