Closed
Description
From @ThatGuyCND @rjmill and myself:
Based on reading https://json-schema.org/understanding-json-schema/structuring.html#using-id-with-ref:
In an effort to reuse definitions and lessen code duplication, common schemas are abstracted into smaller “chunks.”
As noted by the documentation linked above, you would either:
- Use local definitions to define these and then reference them via fragment
#/definitions
- Define them with
$id
(id
in draft-04) and call them that way :#<$id>
- Need to use fragment
#/properties
Assumptions:
- Given the structure of the files below, because id is not defined, and the properties are specified in an external file, and JSON-Schema documentation notes that
definitions
are not required, one would need to use#/properties/…
in order to interpolate the defined values.- When you use $id, you're explicitly setting the "canonical" URI for that schema resource. Unless $id specifies an absolute URI, the URI-reference is resolved against the current base URI to create an absolute URI.
The thing to note here is the base URI. $ref (unless it's an absolute URI) is resolved against the current base URI to create a full URI.
When the base URI isn't explicitly set in the root schema via $id, it defaults to the retrieval URI. So if you retrieved the first one from http://example.com/foo/image_embed.json, the "$ref": "link.json" would be resolved as "$ref": "http://example.com/foo/link.json" as per standard URI resolution rules.
As long as your JSON Schema implementation fetches unknown URIs, and the two schemas are retrievable next to each other, then that should work.
Worth noting, JSON Schema implementations aren't required to fetch unknown URIs. Many do, but it's not a requirement. The URI is being used as an identifier, not a location.$id
as a root-level value and$id
as a property-level value in a schema act on different sides of the JSON Pointer. A root level$id
acts on the left side of the#/
pointer, while a property-level$id
acts on the right side.
Examples:
image_embed.json
:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Image embed",
"description": "A method for displaying images",
"category": "component",
"type": "object",
"format": "grid",
"properties": {
"link": {
"entity": "link",
"type": "object",
"format": "grid",
"options": {
"grid_columns": 6
},
"properties": {
"href": {
"$ref": "link.json#/properties/href",
"options": {
"grid_columns": 3
}
},
"title": {
"$ref": "link.json#/properties/title",
"options": {
"grid_columns": 3
}
}
},
"required": ["href"]
}
}
}
link.json
:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"category": "atom",
"title": "Link",
"entity": "link",
"type": "object",
"format": "grid",
"properties": {
"href": {
"title": "URL",
"type": "string",
"format": "url",
"options": {
"grid_columns": 4
}
},
"title": {
"title": "Title attribute",
"description": "Shown on mouseover.",
"type": "string",
"options": {
"grid_columns": 4
}
}
}
}
the bits in question:
"$ref": "link.json#/properties/href"
, and"$ref": "link.json#/properties/title"
.
Why is this important enough to merit changes to the docs?
"definitions"
/"$defs"
are not required by the spec, therefore most developers are unlikely to use them. Just take a look at any of the large libraries that use JSON Schema to define their schema - for example https://explore.fast.design/components/fast-accordion
Goal
- Get a canonical response here to this discussion, then create a https://github.com/json-schema-org/understanding-json-schema issue + PR for updating the website docs with a canonical explanation of how this functions, with examples.
Metadata
Metadata
Assignees
Labels
No labels