reflect / plugin-rules
Add request search paramter and request body constraints to an API built with Reflect
README
This request pre-processor adds request validation for an API written in the Reflect API Framework.
Write safer Reflect endpoints by enforcing request data structure validation before the request reaches your endpoint's logic. This plugin validates GET and POST data (even JSON) and returns an array with scoped Error
s that can be further acted upon if desired.
Example
POST Request: /my-endpoint?key1=lorem-ipsum&key2=dolor
POST Body: {"key3":15, "key4":["hello", "world"]}
use \Reflect\Endpoint;
use \Reflect\Response;
use \ReflectRules\Type;
use \ReflectRules\Rules;
use \ReflectRules\Ruleset;
class POST_MyEndpoint implements Endpoint {
private Ruleset $rules;
public function __construct() {
$this->rules = new Ruleset();
$this->rules->GET([
(new Rules("key1")
->required()
->type(Type::STRING)
->min(5)
->max(50),
(new Rules("key2")
->required()
->type(Type::NUMBER)
->max(255)
]);
$this->rules->POST([
(new Rules("key3")
->type(Type::ARRAY)
->min(3),
(new Rules("key4")
->required()
->type(Type::STRING)
->max(255)
]);
}
public function main(): Response {
return new Response("Request is valid!");
}
}
Ruleset->get_errors();
[
"GET" => [
"key2" => [
"INVALID_PROPERTY_TYPE" => ["STRING"]
]
],
"POST" => [
"key3" => [
"VALUE_MIN_ERROR" => 3
],
"key4" => [
"MISSING_REQUIRED_PROPERTY" => "key4"
]
]
]
Use Ruleset->is_valid(): bool
to quickly check if any errors are set.
You can also use Ruleset->validate_or_exit(): true|Response
to automatically return a Reflect\Response
with all errors to current STDOUT if validation fails.
Installation
Install with composer
composer require reflect/plugin-rules
Include (at least) Ruleset
and Rules
in your endpoint file
use \ReflectRules\Rules;
use \ReflectRules\Ruleset;
Instantiate a new Ruleset
public function __construct() {
$this->rules = new Ruleset();
}
Run a GET
and/or POST
validation with the GET()
and POST()
Ruleset
methods anywhere before you expect data to be valid
public function __construct() {
$this->rules = new Ruleset();
$this->rules->GET(<Rules_Array>);
}
Errors
Error
--|
Error::VALUE_MIN_ERROR
Error::VALUE_MAX_ERROR
Error::UNKNOWN_PROPERTY_NAME
Error::INVALID_PROPERTY_TYPE
Error::INVALID_PROPERTY_VALUE
Error::MISSING_REQUIRED_PROPERTY
Strict mode
Enable strict mode by initializing a Ruleset with the "strict" argument set to true
.
new Ruleset(strict: true);
Strict mode will not allow undefined properties to be set in all configured scopes. If a property exists in Scope
that hasn't been defined with a Rules()
instance, a Errors::UNKNOWN_PROPERTY_NAME
error will be set.
Available rules
The following methods can be chained onto a Rules
instance to enforce certain constraints on a particular property
required()
Rules->required(bool = true);
Make a property mandatory by chaining the required()
method. Omitting this rule will only validate other rules on the property IF the key has been provided in the current scope.
Will set a Error::MISSING_REQUIRED_PROPERTY
error on the current scope and property if failed.
type()
Rules->type(Type);
Enforce a data type on the request by chaining the type()
method and passing it one of the available enum Type
s as its argument.
[!TIP] Allow multiple types (union) by chaining multiple
type()
methods// Example Rules->type(Type::NUMBER)->type(Type::NULL);
Types
Type | Description |
---|---|
Type::NUMERIC | Value must be a number or a numeric string |
Type::STRING | Value must be a string |
Type::BOOLEAN | Value must be a boolean (considered bool for GET rules) |
Type::ARRAY | Value must be a JSON array or (CSV for GET rules) |
Type::OBJECT | Value must be a JSON object |
Type::ENUM | Value must be exactly one of pre-defined values (more information) |
Type::NULL | Value must be null (considered null for GET rules) |
Will set a Error::INVALID_PROPERTY_TYPE
error on the current scope and property if failed, except Type::ENUM that will set a Error::INVALID_PROPERTY_VALUE
with an array of the valid vaules.
Type::ENUM
Provided value for property must be an exact match of any value provided as an array
to the second argument of type(Type::ENUM, <whitelist>)
Rules->type(Type::ENUM, [
"FOO",
"BAR"
]);
Any value that isn't "FOO"
or "BAR"
will be rejected.
Will set a Error::INVALID_PROPERTY_VALUE
error on the current scope and property if failed.
Boolean coercion from string for search parameters
Search parameters are read as strings, a boolean is therefor coerced from the following rules.
Value | Coerced to |
---|---|
"true" | true |
"1" | true |
"on" | true |
"yes" | true |
-- | -- |
"false" | false |
"0" | false |
"off" | false |
"no" | false |
Any other value will cause the type()
rule to fail.
[!IMPORTANT] This coercion is only applies for
Ruleset->GET()
.Ruleset->POST()
will enforce realtrue
andtype
values since it's JSON
CSV array for search parameters
A CSV string is expected when Type::ARRAY
is set for a GET rule.
Example:
https://example.com?typeArray=key1,key2,key3
Any other value will cause the type()
rule to fail.
[!IMPORTANT] This coercion is only applies for
Ruleset->GET()
.Ruleset->POST()
will enforce a JSON array
Null coercion from string for search parameters
Search parameters are read as strings, a null value is therefor coerced from an empty string ""
.
Any value that isn't an empty string will cause the type()
rule to fail.
[!IMPORTANT] This coercion is only applies for
Ruleset->GET()
.Ruleset->POST()
will enforce the realnull
value since it's JSON
default()
Rules->default(mixed);
Set superglobal property to a defined default value if the property was not provided in superglobal scope
min()
Rules->min(?int = null);
Enforce a minimum length/size/count on a propety depending on its type()
Type | Expects |
---|---|
Type::NUMERIC | Number to be larger or equal to provided value |
Type::STRING | String length to be larger or equal to provided value |
Type::ARRAY , Type::OBJECT | Array size or object key count to be larger or equal to provided value |
min()
will not have an effect on Type
s not provided in this list.
Will set a Error::VALUE_MIN_ERROR
error on the current scope and property if failed
max()
Rules->max(?int = null);
Enforce a maximum length/size/count on a propety depending on its type()
Type | Expects |
---|---|
Type::NUMERIC | Number to be smaller or equal to provided value |
Type::STRING | String length to be smaller or equal to provided value |
Type::ARRAY , Type::OBJECT | Array size or object key count to be smaller or equal to provided value |
max()
will not have an effect on Type
s not provided in this list.
Will set a Error::VALUE_MAX_ERROR
error on the current scope and property if failed