$dynamicRef : URI Reference
$dynamicRef
URI ReferenceThis keyword is used to reference an identified schema, deferring the full resolution until runtime, at which point it is resolved each time it is encountered while evaluating an instance.
Value |
This keyword must be set to an absolute URI or a relative reference as defined by RFC 3986, where its fragment (if any) can consist of a JSON Pointer as defined by RFC 6901
Hint: Use the jsonschema metaschema and jsonschema lint commands to catch keywords set to invalid values
|
---|---|
Kind | Applicator |
Applies To | Any |
Base Dialect | 2020-12 |
Changed In | None |
Introduced In | 2020-12 |
Vocabulary | Core |
Specification | https://json-schema.org/draft/2020-12/json-schema-core.html#section-8.2.3.1 |
Metaschema | https://json-schema.org/draft/2020-12/meta/core |
Official Tests | draft2020-12/dynamicRef.json |
Default | None |
Annotation | None |
Affected By | |
Affects | None |
Also See |
The $dynamicRef
keyword is an
extension of the $ref
keyword that enables
a schema to reference another schema by its dynamic anchor, as declared by the
$dynamicAnchor
keyword. When
resolving a dynamic anchor using this keyword, the base URI of the origin is
not considered. Instead, the evaluator looks in the dynamic
scope and jumps to
the first encountered occurence of the given dynamic anchor in the stack of
schema
resources
traversed so far.
In other words, think of a schema declaring a dynamic reference as a
reference that considers that its destination might have been re-defined by a
parent schema. For example, a schema that dynamically references an anchor
foo
says: “jump to the location set by the foo
anchor, but if there are
overriden variants of it, jump to the first of those instead”.
Best Practice
Use dynamic references when you need to define generic and extensible schemas. In fact, the dynamic referencing mechanism is a direct translation of generic programming facilities like C++ template parameters and Java generics to JSON Schema. See the blog post Using Dynamic References to Support Generic Types by Greg Dennis (co-author of the JSON Schema specification) for a hands-on discussion of this concept.
Digging Deeper
The official JSON Schema meta-schemas define, by convention, a dynamic anchor
called meta
. This is a fundamental building block for schema extensibility.
The meta-schema of every vocabulary (official or third-party) hooks into this
dynamic anchor to extend the recursive definition of what constitutes a valid
schema for the given dialect.
More specifically, by relying on the meta
dynamic anchor, a vocabulary
meta-schema can validate the presence of a new keyword and have those
constraints be automatically discovered and applied by any applicator of any
other vocabulary (even future ones).
Common Pitfall
As a fallback, the specification allows the use of this keyword to reference
static resources and non-dynamic anchors. However, to avoid confusion and keep
your schemas easy to understand, don’t rely on this fallback behaviour. Only
make use of this keyword to reference dynamic anchors set by the
$dynamicAnchor
keyword, without
making use of any URI component (other than the fragment) as part of the
reference.
To debug which dynamic anchor the evaluation process is jumping to, try the
jsonschema validate
command with the --trace
option. This option prints a trace of every step in
the evaluation process alongside the corresponding keywords and their
respective locations, letting you know which destination was preferred when
encountering a dynamic reference. For example:
$ jsonschema validate string-list.json instance.json --resolve generic-list.json --trace
...
-> (push) "/$ref/items/$dynamicRef" (ControlDynamicAnchorJump)
at "/0"
at keyword location "https://example.com/generic-list#/items/$dynamicRef"
at vocabulary "https://json-schema.org/draft/2020-12/vocab/core"
-> (push) "/$ref/items/$dynamicRef/type" (AssertionTypeStrict)
at "/0"
at keyword location "https://example.com/string-list#/$defs/generic-list-item/type"
at vocabulary "https://json-schema.org/draft/2020-12/vocab/validation"
...
Examples
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/generic-list",
"type": "array",
"items": {
"$dynamicRef": "#generic-list-item"
},
"$defs": {
"default": {
"$comment": "This is a default declaration to satisfy the bookending requirement",
"$dynamicAnchor": "generic-list-item"
}
}
}
[]
[ 1, "foo", false ]
{ "keyword": "/items", "instance": "", "value": true }
"Hello World"
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/string-list",
"$ref": "https://example.com/generic-list",
"$defs": {
"generic-list-item": {
"$dynamicAnchor": "generic-list-item",
"type": "string"
}
}
}
[]
[ 1, "foo", false ]
[ "foo", "bar", "baz" ]
{ "keyword": "/$ref/items", "instance": "", "value": true }
"Hello World"