Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/karenetheridge/JSON-Schema-Tiny

Validate data against a schema, minimally
https://github.com/karenetheridge/JSON-Schema-Tiny

Last synced: 4 months ago
JSON representation

Validate data against a schema, minimally

Lists

README

        

=pod

=encoding UTF-8

=for stopwords schema subschema metaschema validator evaluator

=head1 NAME

JSON::Schema::Tiny - Validate data against a schema, minimally

=head1 VERSION

version 0.022

=head1 SYNOPSIS

my $data = { hello => 1 };
my $schema = {
type => "object",
properties => { hello => { type => "integer" } },
};

# functional interface:
use JSON::Schema::Tiny qw(evaluate);
my $result = evaluate($data, $schema); # { valid => true }

# object-oriented interface:
use JSON::Schema::Tiny;
my $js = JSON::Schema::Tiny->new;
my $result = $js->evaluate($data, $schema); # { valid => true }

=head1 DESCRIPTION

This module aims to be a slimmed-down L evaluator and
validator, supporting the most popular keywords.
(See L below for exclusions.)

=head1 FUNCTIONS

=for Pod::Coverage is_type get_type is_equal is_elements_unique jsonp canonical_uri E abort
assert_keyword_type assert_pattern assert_uri assert_non_negative_integer assert_array_schemas
new assert_uri_reference sprintf_num

=head2 evaluate

my $result = evaluate($data, $schema);

Evaluates the provided instance data against the known schema document.

The data is in the form of an unblessed nested Perl data structure representing any type that JSON
allows: null, boolean, string, number, object, array. (See L below.)

The schema must represent a valid JSON Schema in the form of a Perl data structure, such as what is
returned from a JSON decode operation.

With default configuration settings, the return value is a hashref indicating the validation success
or failure, plus (when validation failed), an arrayref of error strings in standard JSON Schema
format. For example:

running:

$result = evaluate(1, { type => 'number' });

C<$result> is:

{ valid => true }

running:

$result = evaluate(1, { type => 'number', multipleOf => 2 });

C<$result> is:

{
valid => false,
errors => [
{
instanceLocation => '',
keywordLocation => '/multipleOf',
error => 'value is not a multiple of 2',
},
],
}

When L> is true, the return value is a boolean (indicating evaluation success or
failure).

=head1 OPTIONS

All options are available as package-scoped global variables. Use L to
configure them for a local scope. They may also be set via the constructor, as lower-cased values in
a hash, e.g.: C<< JSON::Schema::Tiny->new(boolean_result => 1, max_traversal_depth => 10); >>

=head2 C<$BOOLEAN_RESULT>

When true, L will return a true or false result only, with no error strings. This enables
short-circuit mode internally as this cannot effect results except get there faster. Defaults to false.

=head2 C<$SHORT_CIRCUIT>

When true, L will return from evaluating each subschema as soon as a true or false result
can be determined. When C<$BOOLEAN_RESULT> is false, an incomplete list of errors will be returned.
Defaults to false.

=head2 C<$MAX_TRAVERSAL_DEPTH>

The maximum number of levels deep a schema traversal may go, before evaluation is halted. This is to
protect against accidental infinite recursion, such as from two subschemas that each reference each
other, or badly-written schemas that could be optimized. Defaults to 50.

=head2 C<$SCALARREF_BOOLEANS>

When true, any value that is expected to be a boolean B may also be expressed as
the scalar references C<\0> or C<\1> (which are serialized as booleans by JSON backends).
Defaults to false.

=head2 C<$STRINGY_NUMBERS>

When true, any value that is expected to be a number or integer B may also be
expressed as a string. This applies only to the following keywords:

=over 4

=item *

C (where both C and C (and possibly C) are considered types

=item *

C and C (where the string C<"1"> will match with C<"const": 1>)

=item *

C (where strings and numbers are compared numerically to each other, if either or both are numeric)

=item *

C

=item *

C

=item *

C

=item *

C

=item *

C

=back

This allows you to write a schema like this (which validates a string representing an integer):

type: string
pattern: ^[0-9]$
multipleOf: 4
minimum: 16
maximum: 256

Such keywords are only applied if the value looks like a number, and do not generate a failure
otherwise. Values are determined to be numbers via L.
Defaults to false.

=head2 C<$SPECIFICATION_VERSION>

When set, the version of the draft specification is locked to one particular value, and use of
keywords inconsistent with that specification version will result in an error. Will be set
internally automatically with the use of the C<$schema> keyword. When not set, all keywords will be
honoured (when otherwise supported).

Supported values for this option, and the corresponding values for the C<$schema> keyword, are:

=over 4

=item *

L or C<2020-12>|https://json-schema.org/specification-links.html#2020-12>, corresponding to metaschema C

=item *

L or C<2019-09>|https://json-schema.org/specification-links.html#2019-09-formerly-known-as-draft-8>, corresponding to metaschema C

=item *

L or C<7>|https://json-schema.org/specification-links.html#draft-7>, corresponding to metaschema C

=back

Defaults to undef.

=head1 UNSUPPORTED JSON-SCHEMA FEATURES

Unlike L, this is not a complete implementation of the JSON Schema
specification. Some features and keywords are left unsupported in order to keep the code small and
the execution fast. These features are not available:

=over 4

=item *

any output format other than C (when C<$BOOLEAN_RESULT> is true) or C (when it is false)

=item *

L in successful evaluation results

=item *

use of C<$ref> other than to locations in the local schema in json-pointer format (e.g. C<#/path/to/property>). This means that references to external documents, either those available locally or on the network, are not permitted.

=back

In addition, these keywords are implemented only partially or not at all (their presence in a schema
will be ignored or possibly result in an error):

=over 4

=item *

C<$schema> - only accepted if set to one of the specification metaschema URIs (see L<$SPECIFICATION_VERSION> for supported values)

=item *

C<$id>

=item *

C<$anchor>

=item *

C<$recursiveAnchor> and C<$recursiveRef> (draft2019-09), and C<$dynamicAnchor> and C<$dynamicRef> (draft2020-12 and thereafter)

=item *

C<$vocabulary>

=item *

C and C (which require annotation support)

=item *

C (does not cause an error when used)

=back

For a more full-featured implementation of the JSON Schema specification, see
L.

=head1 LIMITATIONS

=head2 Types

Perl is a more loosely-typed language than JSON. This module delves into a value's internal
representation in an attempt to derive the true "intended" type of the value. However, if a value is
used in another context (for example, a numeric value is concatenated into a string, or a numeric
string is used in an arithmetic operation), additional flags can be added onto the variable causing
it to resemble the other type. This should not be an issue if data validation is occurring
immediately after decoding a JSON (or YAML) payload.

For more information, see L.

=head1 SECURITY CONSIDERATIONS

The C and C keywords evaluate regular expressions from the schema.
No effort is taken (at this time) to sanitize the regular expressions for embedded code or
potentially pathological constructs that may pose a security risk, either via denial of service
or by allowing exposure to the internals of your application. B

=head1 SEE ALSO

=over 4

=item *

L: a more specification-compliant JSON Schema evaluator

=item *

L: contains the official JSON Schema test suite

=item *

L

=item *

L: tutorial-focused documentation

=back

=for stopwords OpenAPI

=head1 SUPPORT

Bugs may be submitted through L.

I am also usually active on irc, as 'ether' at C and C.

You can also find me on the L and L, which are also great resources for finding help.

=head1 AUTHOR

Karen Etheridge

=head1 CONTRIBUTOR

=for stopwords Matt S Trout

Matt S Trout

=head1 COPYRIGHT AND LICENCE

This software is copyright (c) 2021 by Karen Etheridge.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut