$dynamicRef : URI Reference

$dynamicRef

URI Reference

This 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”.

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

A generic schema that describes an array where the items definition (by default anything) can be overriden through a dynamic anchor Schema
{
  "$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"
    }
  }
}
Valid An empty array value is valid Instance
[]
Valid An array value with arbitrary items is valid Instance
[ 1, "foo", false ]
Annotations
{ "keyword": "/items", "instance": "", "value": true }
Invalid A non-array value is invalid Instance
"Hello World"
A schema that specialises the previous generic schema to declare that array items must be strings Schema
{
  "$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"
    }
  }
}
Valid An empty array value is valid Instance
[]
Invalid An array value with arbitrary items is invalid Instance
[ 1, "foo", false ]
Valid An array value with string items is valid Instance
[ "foo", "bar", "baz" ]
Annotations
{ "keyword": "/$ref/items", "instance": "", "value": true }
Invalid A non-array value is invalid Instance
"Hello World"