$schema The document decides
A document is read at the version it names, whatever the argument says. The argument is the fallback for a document that names nothing — never an override of one that does.
Five versions, one walk
moonschema validates a JSON instance against a JSON Schema. You hand it a
Json tree; it answers yes or no, and when the answer is no it says where —
in the instance, and in the schema. Five versions of the specification, one validator,
no sockets.
In the browser, on the real engine
A schema on the left, an instance on the right. Edit either: the package compiled to JavaScript validates as you type, and prints every reason it had.
Schema::new once, then valid or faults.
What it holds to
The specification is large and most of it is small print. These are the parts that decide whether a validator is useful or merely present.
A document is read at the version it names, whatever the argument says. The argument is the fallback for a document that names nothing — never an override of one that does.
A fault names the place in the instance and the keyword that refused it, so a message
can point at both. at is a JSON Pointer; so is schema_at.
A validator should not fetch. A $ref reaches a map of documents you fill
in; what is not handed over does not resolve, and that is a fault, not a pass.
What an applicator evaluated is passed to its neighbours, so
unevaluatedProperties sees the branches of an allOf — which
is the only way to close a composed object.
\d, \w, \s and \p{Letter} work as
the specification writes them, read by moonregex's ECMA-262 dialect with the
u flag; scripts and binary properties too, from Unicode 17.0.
A $schema naming a version this does not know is refused when the schema
is read — not read at a version of someone else's choosing.
The five
Five released versions are still in use, so five are here. The value on the left is the
enum; the URI is what a document writes in $schema.
| Draft | $schema | What it is |
|---|---|---|
| Draft4 | json-schema.org/draft-04/schema# |
What OpenAPI 3.0 profiles, and what much Java and Python tooling still emits. |
| Draft6 | json-schema.org/draft-06/schema# |
$id replaces id; exclusiveMinimum becomes a number. |
| Draft7 | json-schema.org/draft-07/schema# |
The most widely deployed version. |
| Draft2019 | json-schema.org/draft/2019-09/schema |
Vocabularies, $defs, $recursiveRef, unevaluatedProperties. |
| Draft2020 | json-schema.org/draft/2020-12/schema |
$dynamicRef, prefixItems — and what OpenAPI 3.1 is. |
Both http and https spellings are accepted, with or without the trailing #.
Where the cloth ends
Four decisions, each with a reason, so that nobody has to discover them by finding the hole.
$refA validator that opens sockets is a validator that blocks, retries and fails. The seam is remotes: a map from URI to document, filled by the caller.
formatThe specification makes format an annotation unless a caller asks otherwise. This does not offer the otherwise yet, so nothing is asserted.
Links and media types are a different specification. This one is validation.
Interpretation first. If it measures slow, that is the time to argue about it — not before there is a number.
Runnable
Each is a small program with its real output, and runs with moon run src/examples/….