JSON-Schema-Validate

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN


- Booleans

    For practicality in Perl, `type => 'boolean'` accepts JSON-like booleans (e.g. true/false, 1/0 as strings) as well as Perl boolean objects (if you use a boolean class). If you need stricter behaviour, you can adapt `_match_type` or introduce a co...

- Combinators `allOf`, `anyOf`, `oneOf`, `not`

    `allOf` validates all subschemas and merges their annotations (e.g. evaluated properties/items) into the parent schema’s annotation. If any subschema fails, `allOf` fails.

    `anyOf` and `oneOf` always validate their branches in a “shadow” context.
    Errors produced by non-selected branches do not leak into the main context when the combinator as a whole succeeds. When `anyOf` fails (no branch matched) or `oneOf` fails (zero or more than one branch matched), the validator merges the collected...

    `not` is also evaluated in a shadow context. If the inner subschema validates, `not` fails with a single “forbidden not-schema” error; otherwise `not` succeeds and any inner errors are discarded.

- Conditionals `if` / `then` / `else`

    The subschema under `if` is treated purely as a condition:

    - `if` is always evaluated in an isolated “shadow” context. Any errors it produces (for example from `required`) are never reported directly.
    - If `if` succeeds and `then` is present, `then` is evaluated against the real context and may produce errors.
    - If `if` fails and `else` is present, `else` is evaluated against the real context and may produce errors.

    This matches the JSON Schema 2020-12 intent: only `then`/`else` affect validity, `if` itself never does.

- `unevaluatedItems` / `unevaluatedProperties`

    Both `unevaluatedItems` and `unevaluatedProperties` are enforced using annotation produced by earlier keyword evaluations within the same schema object, matching draft 2020-12 semantics.

- Error reporting and pointers

    Each error object contains both:

    - `path` – a JSON Pointer-like path to the failing location in the instance (e.g. `#/properties~1s/oneOf~11/properties~1classes/0`).
    - `schema_pointer` – a JSON Pointer into the root schema that identifies the keyword which emitted the error (e.g.
    `#/properties~1s/oneOf~11/properties~1classes/items/allOf~10/then/voting_right`).

    Messages for `required` errors also list the full required set and the keys actually present at that location to help debug combinators such as `anyOf`/`oneOf`/`if`/`then`/`else`.

- RFC rigor and media types

    [URI](https://metacpan.org/pod/URI)/`IRI` and media‐type parsing is intentionally pragmatic rather than fully RFC-complete. For example, `uri`, `iri`, and `uri-reference` use strict but heuristic regexes; `contentMediaType` validates UTF-8 for ...

- Compilation vs. Interpretation

    Both code paths are correct by design. The interpreter is simpler and great while developing a schema; toggle `->compile` when moving to production or after the schema stabilises. You may enable compilation lazily (call `compile` any time) or eag...

# WHY ENABLE `COMPILE`?

When `compile` is ON, the validator precompiles a tiny Perl closure for each schema node. At runtime, those closures:

- avoid repeated hash lookups for keyword presence/values;
- skip dispatch on absent keywords (branchless fast paths);
- reuse precompiled child validators (arrays/objects/combinators);
- reduce allocator churn by returning small, fixed-shape result hashes.

In practice this improves steady-state throughput (especially for large/branchy schemas, or hot validation loops) and lowers tail latency by minimising per-instance work. The trade-offs are:

- a one-time compile cost per node (usually amortised quickly);
- a small memory footprint for closures (one per visited node).

If you only validate once or twice against a tiny schema, compilation will not matter; for services, batch jobs, or streaming pipelines it typically yields a noticeable speedup. Always benchmark with your own schema+data.

# AUTHOR

Jacques Deguest <`jack@deguest.jp`>

# SEE ALSO

[perl](https://metacpan.org/pod/perl), [DateTime](https://metacpan.org/pod/DateTime), [DateTime::Format::ISO8601](https://metacpan.org/pod/DateTime%3A%3AFormat%3A%3AISO8601), [DateTime::Duration](https://metacpan.org/pod/DateTime%3A%3ADuration), [Reg...

[JSON::Schema](https://metacpan.org/pod/JSON%3A%3ASchema), [JSON::Validator](https://metacpan.org/pod/JSON%3A%3AValidator)

[python-jsonschema](https://github.com/python-jsonschema/jsonschema),
[fastjsonschema](https://github.com/horejsek/python-fastjsonschema),
[Pydantic](https://docs.pydantic.dev),
[RapidJSON Schema](https://rapidjson.org/md_doc_schema.html)

[https://json-schema.org/specification](https://json-schema.org/specification)

# COPYRIGHT & LICENSE

Copyright(c) 2025 DEGUEST Pte. Ltd.

All rights reserved.

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

# POD ERRORS

Hey! **The above document had some coding errors, which are explained below:**

- Around line 4833:

    Unterminated C<...> sequence

    Unknown E content in E&lt;gt 200>



( run in 0.523 second using v1.01-cache-2.11-cpan-39bf76dae61 )