Validate::Simple - (Relatively) Simple way to validate input parameters
use Validate::Simple; my $specs = { username => { type => 'string', required => 1, }, first_name => { type => 'string', required => 1, }, last_name => { type => 'string', }, age => { type => 'integer', gt => 18, }, gender => { type => 'enum', values => [ 'male', 'female', 'id_rather_not_to_say', ], }, tags => { type => 'array', of => { type => 'string', }, }, hobbies => { type => 'array', of => { type =>'enum', values => [ qw/hiking travelling surfing laziness/ ], }, }, score => { type => 'hash', of => { type => 'non_negative_int', }, }, monthly_score => { type => 'hash', of => { type => 'hash', of => { type => 'array', of => { type => 'non_negative_int', }, callback => sub { @{ $_[0] } < 12; }, }, }, }, address => { type => 'spec', of => { country => { type => 'enum', values => [ qw/ af ax al ... zw / ], }, zip_code => { type => 'string', }, street => { type => 'string', }, number => { type => 'spec', of => { house_nr => { type => 'positive_int', }, house_ext => { type => 'string', }, apt => { type => 'positive_int', }, }, }, }, }, }; my $vs1 = Validate::Simple->new( $specs ); my $is_valid1 = $vs1->validate( $params ); print join "\n", $vs1->errors() if !$is_valid1; # Or my $vs2 = Validate::Simple->new(); my $is_valid2 = $vs2->validate( $params, $specs ); print join "\n", $vs2->errors() if !$is_valid2;
The module validates parameters against specifications.
The general use case is the like this.
You have a from handler or a handler of an API endpoint. It receives a hashref as a parameter. You want to make sure that the input hashref has all the required keys, you do not have unknown keys, and all the values satisfy certain criterias: type, size and other constraints...
Validate::Simple allows you to specify criterias for each input parameter in a (relatively) simple form and validate user input against your specification as many times as you need. A specification is just a hashref. The keys repeat parameters names, the values define criterias.
Validate::Simple
For example:
my $specs = { username => { type => 'string', required => 1, min_length => 1, max_length => 255, }, password => { type => 'string', required => 1, min_length => 12, }, subscriptions => { type => 'array', empty => 0, of => { type => 'positive_int', }, } };
This specification can be used to validate a sign up form. Validation passes only if user enters a non-empty username no longer than 255 character, a password no shorter than 12 characters and chooses 0 or more subscriptions (which are supposed to be provided as a list of IDs, i.e. positive integers. The list of subscriptions may absent (no required key in the rule), but if it exists, it cannot be empty (because of the value of the empty key is set to 0).
required
empty
0
If input data contains a key 'remember_me', validation fails, because specification does not define rules for this key.
'remember_me'
This module does not export anything. It is supposed to be used in OOP approach only.
Specifications are the rules that describe which parameters are expected, their types and constraints (like lengths of strings or signs of numbers). Specification is just a hashref, the keys are parameters names, and the values describe criterias.
Every description must have a type key, and may have the keys required, undef and callback.
type
undef
callback
The value of type defines an expected type of a parameter. If omitted, type 'any' is used. You can learn more about supported types in the "Types" section.
'any'
When it is set to a true value, the parameter is required, and, if it is not in the input data, the form is considered invalid. When it is set to a false value or does not exists, the parameter is optional.
By default none parameters can be undefined. If you expect some values to be undefined, you need to explicitly set this key to true.
For example, if you allow the value of the param to be literally anything, you can do the following:
my $specs = { whatever => { type => 'any', undef => 1, } };
If you have some special constraints to a value that does not fit to any of supported types, you can specify your own validation function and pass it to callback key as a coderef. The function should receive the value as a first parameter and returns true or false.
For example, if you need to check whether a value is an even positive integer, you can do the following:
my $specs = { even_positive => { type => "positive_int", callback => sub { !( $_[0] % 2 ) }, }, };
In case of the "enum" type, the second parameter is the hashref with the keys of allowed enum values.
The callback function is called after checking the type and constraints.
The value can be of any type (including array or hash), except undef.
All number types support the following keys:
Greater than.
Greater than or equal to.
Less than.
Less than or equal to.
For example, the following spec checks whether it's a valid month number:
my $specs = { month => { type => 'positive_int', le => 12, }, };
The value is a valid number. On the backstage it simply performs looks_like_number from Scalar::Util.
Same as "number", and checks whether it's greater than 0.
Same as "number", and checks whether it's greater than or equal to 0.
Same as "number", and checks whether it's less than or equal to 0.
The value is an integer. It performs is_int from Data::Types.
The value is a positive integer. It performs is_count from Data::Types.
The value is a non-negative integer. It performs is_whole from Data::Types.
The value is a negative integer.
The value is a non-positive integer.
The value is a string. It performs is_string from Data::Types.
NOTE: Any number is a valid string, so both $params1 = { string_param => 5 }; and $params1 = { string_param => "5" }; will pass.
$params1 = { string_param => 5 };
$params1 = { string_param => "5" };
You can add the following constraints to a string:
Positive integer number that defines the maximum string length allowed.
Positive integer number that defines the minimum string length allowed.
Regilar expression. The value will be checked aginst this regexp.
my $specs = { str_re => { type => 'string', re => qr/Valid/, } };
The list types must have the key of, which contains a spec of all list values. For example:
of
my $specs = { ids => { type => 'array', of => { type => 'positive_int', }, }, placeholders => { type => 'hash', of => { type => 'string', }, }, };
As long as the of key expects another specification, you can easily validate complex structures, like array of arrays of strings, hash of arrays of hashes of enums, arrays of hashes of arrays of arrays of any, and so on.
By default lists cannot be empty. If you expect an empty list, you should add a key empty and set it to a true value.
The value is an arrayref.
The value is a hashref.
The value is one of the predefined list.
Enum type always contains a string. The list of predefined strings is provided in the values key, which is required for enums:
values
my $specs = { data_types => { type => 'enum', values => [ qw/ any number positive non_negative negative non_positive integer positive_int non_negative_int negative_int non_positive_int string array hash enum code / ], } };
The value is a coderef. Validate::Simple only checks the type, it does not run the code and does not check its result.
The value is another structure, of hashref with predefined keys and values of different types. The type spec requires the key of, which, in turn, expects another valid specification. Obviously, a specification may contain as many nested specifications as necessary.
spec
my $resume_spec = { name => { type => 'string' }, objective => { type => 'string' }, experience => { type => 'array', of => { type => 'spec', of => { company => { type => 'string', }, position => { type => 'string', }, description => { type => 'string', }, start => { type => 'spec', of => { year => { type => 'integer', gt => 1960, le => 1900 + (localtime)[5], }, month => { type => 'positive_int', lt => 12, }, }, required => 1, }, end => { type => 'spec', of => { year => { type => 'integer', gt => 1960, le => 1900 + (localtime)[5], }, month => { type => 'positive_int', lt => 12, }, }, required => 0, }, }, }, }, };
Creates an object. The parameter is optional, though it's recomended to pass it, because in this case it checks specs syntax only once, not on each call of validate method.
validate
By default the module stops validation after finding the first invalid value. If the second parameter $all_errors is true, the call of the validate method will keep checking all \%params and will stack all found errors. The list of errors is returned by the errors method.
$all_errors
\%params
errors
Does validation of the \%params against \%specs. If \%specs is not provided, it performs validation against the spec, given in the new method. Returns 1 if \%params are valid, undef otherwise.
\%specs
new
The parameter $all_errors works the same way as in the new() method.
new()
Returns the list of validation errors. The list is being emptied before each call of the validate method.
Not reported... Yet...
Andrei Pratasavitski <andreip@cpan.org>
This is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
To install Validate::Simple, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Validate::Simple
CPAN shell
perl -MCPAN -e shell install Validate::Simple
For more information on module installation, please visit the detailed CPAN module installation guide.