Git Product home page Git Product logo

reflect-rules-plugin's Introduction

Request validation plugin for the Reflect API Framework

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 Errors that can be further acted upon if desired.

Example:

GET 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 GET_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.

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 Types 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 real true and type 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 real null 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 Types 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 Types not provided in this list.

Will set a Error::VALUE_MAX_ERROR error on the current scope and property if failed

reflect-rules-plugin's People

Contributors

victorwesterlund avatar

Watchers

 avatar

reflect-rules-plugin's Issues

Required constraint sometimes lets undefined fields through

With the following Ruleset:

Ruleset->POST([
    (new Rules("id"))
        ->required()
        ->type(Type::STRING),
    
    (new Rules("user"))
        ->required()
        ->type(Type::STRING)
        ->max(128),
    
    (new Rules("active"))
        ->required()
        ->type(Type::BOOLEAN),
    
    (new Rules("expires"))
        ->required()
        ->type(Type::NUMBER)
        ->max(PHP_INT_MAX)
]);

Sending the following data with Reflect PHP Client syntax:

Client->call("endpoint", Method::PUT, [
  "active" => true
]);

Will still let the request through to main() despite a lot of required() rules missing. The missing rules have their $_POST values set to null, so it does at least initialize processing on them.

Add `Type::ENUM` constraint

A new type ENUM would match the provided value in scope for the property name against an array of allowed values.

For example:

Rule->type(Type::ENUM, [
  "FOO",
  "BAR",
  "BIZ
]);

Any value that doesn't exist in the provided enum will cause the type() constraint to return an error

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.