Request Guards
Incoming requests often require a few checks in order to evaluate their integrity. These checks include
- Is the payload/the query malformed?
- Does the payload correlate to the right types?
- Does the payload need to be sanitized?
The Concept
A request guard captures the request and is in its easiest form similar to a model declaration. By defining properties we decide which properties are optional or required, which properties should be cast into a type, and what default values should be considered. Without further configuration, a request guard ends a request with an error message before executing your controller.
class MyRequest extends \Neoan\Request\RequestGuard
{
// the request REQUIRES the property "email"
public string $email;
// the request REQUIRES the property "name"
public string $name;
// the request CAN have the property "age",
// which will be cast to integer
public ?int $age;
// the request's value of "termsAccepted"
// is cast to boolean
public bool $termsAccepted;
// the request's value of "gender" is
// cast to the custom enum "GenderEnum"
public ?GenderEnum $gender;
}
If the request does not contain all required properties, the request will be blocked. In order to use a request guard for a particular endpoint, inject the guard in the controller.
class MyEndpoint implements Routable
{
// Inject "MyRequest" as $request
public function __invoke(MyRequest $request): array
{
// let's assume we want to create a new person (model)
$person = new Person();
$person->email = $request->email;
if(isset($request->gender){
$person->gender = $request->gender;
}
...
/*
* or "lazy": (new Person((array) $request))->store();
*/
}
}
Error behavior
If a request is not valid, a 400 HTTP response will be sent along with a reason (e.g. "missing property `x`", etc.). However, you might want to turn that behavior off if necessary (e.g. for custom error handling).
class MyRequest extends \Neoan\Request\RequestGuard
{
// if throwOnError is set to false, the default behavior of blocking the request is overridden
const throwOnError = false;
public string $email;
public string $name;
public ?int $age;
public bool $termsAccepted;
public ?GenderEnum $gender;
}
Request Types
By default, the request guard will accept requests of the following types:
- 'query', Query parameters
- 'parameter', as defined as a route-part
- 'post', payload submitted via POST, PUT, PATCH
- 'file', binary file uploads
You can limit the considered request types by the constant "requestTypes".
class MyRequest extends \Neoan\Request\RequestGuard
{
// only consider "query" and "parameter"
const requestTypes = ['query', 'parameter'];
public string $email;
public string $name;
public ?int $age;
public bool $termsAccepted;
public ?GenderEnum $gender;
}
Before you move on
Many references on this page assume default settings. Your project might differ in behavior, paths etc.