NAME

JSON::Schema::Fast - a fast JSON Schema (draft 2020-12) validator

VERSION

Version 0.03

SYNOPSIS

use JSON::Schema::Fast;

# compile a schema once (a hashref, a boolean, or JSON text)
my $v = JSON::Schema::Fast->compile({
    type       => 'object',
    required   => ['name'],
    properties => {
        name => { type => 'string', minLength => 1 },
        age  => { type => 'integer', minimum => 0 },
    },
});

# then validate live Perl data as often as you like
if ($v->is_valid($data)) { ... }                 # fast boolean

my ($ok, $errors) = $v->validate($data);         # collect all errors
for my $e (@$errors) {
    warn "$e->{instanceLocation}: $e->{keyword}\n";
}

DESCRIPTION

JSON::Schema::Fast compiles a JSON Schema once into a compact arena intermediate representation and validates live Perl data through a tight, threaded C interpreter. A compiled schema walks a packed IR with bitmask type checks and pre-hashed property lookups, and allocates nothing on the valid path.

CONSTRUCTOR

compile

my $v = JSON::Schema::Fast->compile($schema, %options);

Compiles $schema into a JSON::Schema::Fast::Compiled object. $schema may be:

  • a Perl hashref (the usual form),

  • a boolean schema - the JSON booleans true/false, 1/0, or an empty hashref {} (equivalent to true), or

  • a string of JSON text, which is decoded with File::Raw::JSON.

A schema that uses a remote or otherwise unresolvable $ref, or that is malformed, throws an error.

coerce => 0 | 1 (default 0)

When a type check would fail because the value is a string, accept it if it can stand in for a permitted type: a numeric string satisfies number (and integer when integral), and "true"/"false" satisfy boolean. The numeric keywords (minimum, multipleOf, ...) then apply to the numeric value. Coercion never changes the caller's value. This is what lets OpenAPI string parameters validate against a typed schema.

apply_defaults => 0 | 1 (default 0)

Before validating an object, fill any missing property that declares a default into the callers data.

ERRORS

validate and errors return errors as an arrayref of plain hashes, each with the trimmed draft 2020-12 output fields:

instanceLocation

An RFC 6901 JSON Pointer into the data ("/items/3/age", or "" for the root). ~ and / in property names are escaped as ~0 and ~1.

keyword

The failing keyword (type, required, minimum, ...).

schemaLocation

A JSON Pointer into the schema ("/properties/age/minimum").

message

A short human-readable string.

All independent failures are collected, in a deterministic depth-first order. The boolean is_valid short-circuits on the first failure and does none of this work.

KEYWORD COVERAGE (v0.03)

The supported draft 2020-12 subset:

  • Core: $ref (same-document JSON Pointer, including percent- and ~-escaped fragments), $defs, $id (parsed, local only).

  • Type: type (string or array), enum, const.

  • Number: minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf.

  • String: minLength, maxLength (counted in codepoints), pattern (compiled once, cached), format (annotation only).

  • Array: items, prefixItems, minItems, maxItems, uniqueItems, contains (with minContains/maxContains).

  • Object: properties, patternProperties, additionalProperties, required, minProperties, maxProperties, propertyNames, dependentRequired, dependentSchemas.

  • Applicators: allOf, anyOf, oneOf, not, if/then/else.

A keyword outside this set is parsed and ignored, and recorded so a schema that relies on it can be identified rather than silently mis-validated.

JSON Schema types follow the JSON value's type, not Perl's DWIM: a numeric string is a string unless coerce is set.

FUTURE

Deferred to a later release: remote / cross-document $ref and $anchor / $id-relative resolution; unevaluatedProperties / unevaluatedItems; $dynamicRef and custom $vocabulary.

PERFORMANCE

A compiled schema is validated by walking a packed arena with no re-reading of the schema document and no allocation on the valid path (errors, pattern compilation and uniqueItems are the only things that allocate, and only when present).

SEE ALSO

JSON::Schema::Fast::Compiled (the compiled-object methods), File::Raw::JSON (JSON parsing), JSON::Schema::Modern.

AUTHOR

LNATION <email@lnation.org>

LICENSE AND COPYRIGHT

This software is Copyright (c) 2026 by LNATION <email@lnation.org>.

This is free software, licensed under the Artistic License 2.0 (GPL Compatible).