The presence of the $id
field in the following JSON Schema causes a jsonschema.exceptions._WrappedReferencingError
when I try to call jsonschema.validate on it using the jsonref library in python.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"first_definition": {
"value": "this is definitions/first_definition"
},
"second_definition": {
"$id": "any_value",
"properties": {
"sections": {
"$ref": "#/definitions/first_definition"
}
}
}
},
"$ref": "#/definitions/second_definition"
}
Apparently having an $id
changes the scope that $ref can see? The $ref that fails is the '/definitions/first_definition'
ref, and the WrappedReferencingError holds a referencing.exceptions.PointerToNowhere'. I can remove the $id
to get rid of the error, but that seems like the wrong solution. Is there a way to still have an $id
, but without breaking the $ref?
Why do you think you need the $id
? I'm just curious if you think there is use case you believe it solves.
The $id
acts as a scoping mechanism. It's an identifier for a schema. Essentially, it's creating a new "file" of just that schema. so the use of #/definitions/first_definition
means it's looking for the first_definition
in the any_value
schema root.
think of it like this..
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"first_definition": {
"value": "this is definitions/first_definition"
},
"second_definition": {
"$id": "any_value",
"properties": {
"sections": {
"$ref": "#/definitions/first_definition"
}
}
}
},
"$ref": "#/definitions/second_definition"
}
any_value
schema.first_definition
is not defined in this schema, so it doesn't resolve to anything, thus throws an error
{
"$id": "any_value",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"sections": {
"$ref": "#/definitions/first_definition"
}
},
"definitions": {}
}
When you remove the $id
, it changes the scope of the #/definitions/...
to the root of the original schema, where it finds the definition for first_definintion
defined.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"first_definition": {
"value": "this is definitions/first_definition"
},
"second_definition": {
"properties": {
"sections": {
"$ref": "#/definitions/first_definition"
}
}
}
},
"$ref": "#/definitions/second_definition"
}
If you really have your heart set on using $id
, you need to give the root schema an id to reference. Then you can resolve the reference.
{
"$id": "root_schema",
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"first_definition": {
"value": "this is definitions/first_definition"
},
"second_definition": {
"$id": "any_value",
"properties": {
"sections": {
"$ref": "root_schema#/definitions/first_definition"
}
}
}
},
"$ref": "#/definitions/second_definition"
}
An alternative to the id reference is to use relative or absolute file path references.
assume the file name is root.schema.json
. This will resolve to the file path and the root of the schema becomes available with the #
which allows you to navigate through the file.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"first_definition": {
"value": "this is definitions/first_definition"
},
"second_definition": {
"$id": "any_value",
"properties": {
"sections": {
"$ref": "./root.schema.json#/definitions/first_definition"
}
}
}
},
"$ref": "#/definitions/second_definition"
}