diff --git a/hyper-schema.json b/hyper-schema.json index bc5ba60d..54728855 100644 --- a/hyper-schema.json +++ b/hyper-schema.json @@ -1,5 +1,5 @@ { - "$schema": "https://json-schema.org/draft/2019-08/hyper-schema#", + "$schema": "https://json-schema.org/draft/2019-08/hyper-schema", "$id": "https://json-schema.org/draft/2019-08/hyper-schema", "$vocabulary": { "https://json-schema.org/draft/2019-08/vocab/core": true, diff --git a/jsonschema-core.xml b/jsonschema-core.xml index 2d91ffe6..78e144a7 100644 --- a/jsonschema-core.xml +++ b/jsonschema-core.xml @@ -2,6 +2,7 @@ + @@ -402,10 +403,17 @@ additional keywords that are not part of a formal vocabulary. -
+
+ + A JSON Schema resource is a schema which is + canonically identified by an + absolute URI. + The root schema is the schema that comprises the entire JSON document - in question. + in question. The root schema is always a schema resource, where the + URI is determined as described in section + . Some keywords take schemas themselves, allowing JSON Schemas to be nested: @@ -429,6 +437,15 @@ As with the root schema, a subschema is either an object or a boolean. + + As discussed in section + , a JSON Schema document + can contain multiple JSON Schema resources. When used without qualification, + the term "root schema" refers to the document's root schema. In some + cases, resource root schemas are discussed. A resource's root schema + is its top-level schema object, which would also be a document root schema + if the resource were to be extracted to a standalone JSON Schema document. +
@@ -466,7 +483,7 @@ Defining and referencing a plain name fragment identifier within an "application/schema+json" document are specified - in the "$id" keyword section. + in the "$anchor" keyword section. @@ -611,7 +628,7 @@ Note that some keywords, such as "$schema", apply to the lexical scope of the entire schema document, and therefore MUST only - appear in the document's root schema. + appear in a schema resource's root schema. Other keywords may take into account the dynamic scope that @@ -1118,11 +1135,15 @@ media type "application/schema+json". - The "$schema" keyword SHOULD be used in a root schema. - It MUST NOT appear in subschemas. If absent from the root schema, the + The "$schema" keyword SHOULD be used in a resource root schema. + It MUST NOT appear in resource subschemas. If absent from the root schema, the resulting behavior is implementation-defined. + If multiple schema resources are present in a single document, then all + schema resources SHOULD Have the same value for "$schema". The result of + differing values for "$schema" within the same schema document is + implementation-defined. Using multiple "$schema" keywords in the same document would imply that the feature set and therefore behavior can change within a document. This would @@ -1132,6 +1153,12 @@ implementation behavior is subject to be revised or liberalized in future drafts. + + The exception made for embedded schema resources is to + allow bundling multiple schema resources into a single schema document + without needing to change their contents, as described later in this + specification. + + The root schema of a JSON Schema document SHOULD contain an "$id" keyword + with an absolute-URI (containing a scheme, + but no fragment). -
+
- When an "$id" sets the base URI, the object containing that "$id" and all of - its subschemas can be identified by using a JSON Pointer fragment starting - from that location. This is true even of subschemas that further change the - base URI. Therefore, a single subschema may be accessible by multiple URIs, - each consisting of base URI declared in the subschema or a parent, along with - a JSON Pointer fragment identifying the path from the schema object that - declares the base to the subschema being identified. Examples of this are - shown in section . + Since JSON Pointer URI fragments are constructed based on the structure + of the schema document, an embedded schema resource and its subschemas + can be identified by JSON Pointer fragments relative to either its own + canonical URI, or relative to the containing resource's URI. + + + Conceptually, a set of linked schema resources should behave + identically whether each resource is a separate document connected with + schema references, or is structured as + a single document with one or more schema resources embedded as + subschemas. -
-
- Using JSON Pointer fragments requires knowledge of the structure of the schema. - When writing schema documents with the intention to provide re-usable - schemas, it may be preferable to use a plain name fragment that is not tied to - any particular structural location. This allows a subschema to be relocated - without requiring JSON Pointer references to be updated. + Since URIs involving JSON Pointer fragments relative to the parent + schema resource's URI cease to be valid when the embedded schema + is moved to a separate document and referenced, applications and schemas + SHOULD NOT use such URIs to identify embedded schema resources or + locations within them. +
+ + Consider the following schema document that contains another + schema resource embedded within it: + + + + + + The URI "https://example.com/foo#/items/additionalProperties" + points to the schema of the "additionalProperties" keyword in + the embedded resource. The canonical URI of that schema, however, + is "https://example.com/bar#/additionalProperties". + +
+
+ + Now consider the following two schema resources linked by reference + using a URI value for "$ref": + + + + + + Here we see that the canonical URI for that "additionalProperties" + subschema is still valid, while the non-canonical URI with the fragment + beginning with "#/items/$ref" now resolves to nothing. + +
- To specify such a subschema identifier, - the "$id" keyword is set to a URI reference with a plain name fragment (not a JSON Pointer fragment). - This value MUST begin with the number sign that specifies a fragment ("#"), - then a letter ([A-Za-z]), - followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), - colons (":"), or periods ("."). + Note also that "https://example.com/foo#/items" is valid in both + arrangments, but resolves to a different value. This URI ends up + functioning similarly to a retrieval URI for a resource. While valid, + examining the resolved value and either using the "$id" (if the value + is a subschema), or resolving the reference and using the "$id" of the + reference target, is preferable. - The effect of using a fragment in "$id" that isn't blank or doesn't follow the - plain name syntax is undefined. + An implementation MAY choose not to support addressing schemas + by non-canonical URIs. As such, it is RECOMENDED that schema authors only + use canonical URIs, as using non-canonical URIs may reduce + schema interoperability. - How should an "$id" URI reference containing a fragment with other components - be interpreted? There are two cases: when the other components match - the current base URI and when they change the base URI. + This is to avoid requiring implementations to keep track of a whole + stack of possible base URIs and JSON Pointer fragments for each, + given that all but one will be fragile if the schema resources + are reorganized. Some have argued that this is easy so there is + no point in forbidding it, while others have argued that it complicates + schema identification and should be forbidden. Feedback on this + topic is encouraged. + + Further examples of such non-canonical URIs, as well as the appropriate + canonical URIs to use instead, are provided in section + . +
-
-
- - Consider the following schema, which shows "$id" being used to identify - the root schema, change the base URI for subschemas, and assign plain - name fragments to subschemas: - - +
+
+ + Using JSON Pointer fragments requires knowledge of the structure of the schema. + When writing schema documents with the intention to provide re-usable + schemas, it may be preferable to use a plain name fragment that is not tied to + any particular structural location. This allows a subschema to be relocated + without requiring JSON Pointer references to be updated. + + + The "$anchor" keyword is used to specify such a fragment. + + + If present, the value of this keyword MUST be a string, which MUST start with + a letter ([A-Za-z]), followed by any number of letters, digits ([0-9]), + hyphens ("-"), underscores ("_"), colons (":"), or periods ("."). + + Note that the anchor string does not include the "#" character, + as it is not a URI-reference. An "$anchor": "foo" becomes the + fragment "#foo" when used in a URI. See below for full examples. + + + + The base URI to which the resulting fragment is appended is determined + by the "$id" keyword as explained in the previous section. + Two "$anchor" keywords in the same schema document MAY have the same + value if they apply to different base URIs, as the resulting full URIs + will be distinct. However, the effect of two "$anchor" keywords with the + same value and the same base URI is undefined. Implementations MAY + raise an error if such usage is detected. + +
+
+
+ + Consider the following schema, which shows "$id" being used to identify + both the root schema and various subschemas, and "$anchor" being used + to define plain name fragment identifiers. + + - -
- - The schemas at the following URI-encoded JSON - Pointers (relative to the root schema) have the following - base URIs, and are identifiable by any listed URI in accordance with - Section above: - - - - - - https://example.com/root.json - https://example.com/root.json# - - - - - https://example.com/root.json#foo - https://example.com/root.json#/$defs/A - - - - - https://example.com/other.json - https://example.com/other.json# - https://example.com/root.json#/$defs/B - - - - - https://example.com/other.json#bar - https://example.com/other.json#/$defs/X - https://example.com/root.json#/$defs/B/$defs/X - - - - - https://example.com/t/inner.json - https://example.com/t/inner.json# - https://example.com/other.json#/$defs/Y - https://example.com/root.json#/$defs/B/$defs/Y - - - - - urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f - urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f# - https://example.com/root.json#/$defs/C - - - - -
+ + + + The schemas at the following URI-encoded JSON + Pointers (relative to the root schema) have the following + base URIs, and are identifiable by any listed URI in accordance with + sections and + above. As previously + noted, support for non-canonical URIs is OPTIONAL. + + + + + + + https://example.com/root.json + + + https://example.com/root.json# + + + + + + https://example.com/root.json + + https://example.com/root.json#foo + + + https://example.com/root.json#/$defs/A + + + + + + https://example.com/other.json + + https://example.com/other.json# + + + https://example.com/root.json#/$defs/B + + + + + + https://example.com/other.json + + https://example.com/other.json#bar + + + https://example.com/other.json#/$defs/X + + + https://example.com/root.json#/$defs/B/$defs/X + + + + + + https://example.com/t/inner.json + + https://example.com/t/inner.json#bar + + + https://example.com/t/inner.json# + + + https://example.com/other.json#/$defs/Y + + + https://example.com/root.json#/$defs/B/$defs/Y + + + + + + + urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f + + + urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f# + + + https://example.com/root.json#/$defs/C + + + + +
-
+
Several keywords can be used to reference a schema which is to be applied to the current instance location. "$ref" and "$recursiveRef" are applicator @@ -1646,11 +1850,9 @@
The "$ref" keyword is used to reference a statically identified schema. - - - The value of the "$ref" property MUST be a string which is a URI Reference. - Resolved against the current URI base, it identifies the URI of a schema - to use. + The value of the "$ref" property MUST be a string which is a URI-Reference. + Resolved against the current URI base, it produces the URI of the schema + to apply.
@@ -1958,7 +2160,7 @@ }, "$defs": { "single": { - "$id": "#item", + "$anchor": "item", "type": "object", "additionalProperties": { "$ref": "other.json" } } @@ -2746,8 +2948,8 @@ https://json-schema.org/draft/2019-08/schema#/$defs/nonNegativeInteger/minimum + &RFC6596; &RFC7049; &RFC7231; &RFC8288; @@ -3432,6 +3635,9 @@ User-Agent: product-name/5.4.1 so-cool-json-schema/1.0.2 curl/7.43.0 Additional guidance on initial base URIs beyond network retrieval Allow "schema" media type parameter for "application/schema+json" Better explanation of media type parameters and the HTTP Accept header + Use "$id" to establish canonical and base absolute-URIs only, no fragments + Replace plain-name-fragment-only form of $id with $anchor + Clarified that the behavior of JSON Pointers across $id boundary is unreliable
diff --git a/jsonschema-hyperschema.xml b/jsonschema-hyperschema.xml index e3ddf254..94b3ecfe 100644 --- a/jsonschema-hyperschema.xml +++ b/jsonschema-hyperschema.xml @@ -1618,7 +1618,7 @@ Link: ; rel="describedBy" ; rel="describedBy" ; rel="describedBy" ; rev="up" ; rev="up" ; rev="up" - The current URI for the JSON Schema Validation meta-schema is - . + The current URI for the default JSON Schema meta-schema is + . For schema author convenience, this meta-schema describes all vocabularies defined in this specification and the JSON Schema Core specification, as well as two former keywords which are reserved for a transitional period. diff --git a/links.json b/links.json index 0e0110db..51aeb18b 100644 --- a/links.json +++ b/links.json @@ -1,5 +1,5 @@ { - "$schema": "https://json-schema.org/draft/2019-08/hyper-schema#", + "$schema": "https://json-schema.org/draft/2019-08/hyper-schema", "$id": "https://json-schema.org/draft/2019-08/links", "title": "Link Description Object", "allOf": [ diff --git a/meta/applicator.json b/meta/applicator.json index d101b710..0ea68635 100644 --- a/meta/applicator.json +++ b/meta/applicator.json @@ -1,5 +1,5 @@ { - "$schema": "https://json-schema.org/draft/2019-08/schema#", + "$schema": "https://json-schema.org/draft/2019-08/schema", "$id": "https://json-schema.org/draft/2019-08/meta/applicator", "$vocabulary": { "https://json-schema.org/draft/2019-08/vocab/applicator": true diff --git a/meta/content.json b/meta/content.json index 185b7a49..cfe98563 100644 --- a/meta/content.json +++ b/meta/content.json @@ -1,5 +1,5 @@ { - "$schema": "https://json-schema.org/draft/2019-08/schema#", + "$schema": "https://json-schema.org/draft/2019-08/schema", "$id": "https://json-schema.org/draft/2019-08/meta/content", "$vocabulary": { "https://json-schema.org/draft/2019-08/vocab/content": true diff --git a/meta/core.json b/meta/core.json index 9dd8fbc2..3f6ad58b 100644 --- a/meta/core.json +++ b/meta/core.json @@ -1,5 +1,5 @@ { - "$schema": "https://json-schema.org/draft/2019-08/schema#", + "$schema": "https://json-schema.org/draft/2019-08/schema", "$id": "https://json-schema.org/draft/2019-08/meta/core", "$vocabulary": { "https://json-schema.org/draft/2019-08/vocab/core": true @@ -11,12 +11,18 @@ "properties": { "$id": { "type": "string", - "format": "uri-reference" + "format": "uri-reference", + "$comment": "Non-empty fragments not allowed.", + "pattern": "^[^#]#?$" }, "$schema": { "type": "string", "format": "uri" }, + "$anchor": { + "type": "string", + "pattern": "^[A-Za-z][-A-Za-z0-9.:_]*$" + }, "$ref": { "type": "string", "format": "uri-reference" diff --git a/meta/format.json b/meta/format.json index 7cbf48d8..8f658c6e 100644 --- a/meta/format.json +++ b/meta/format.json @@ -1,5 +1,5 @@ { - "$schema": "https://json-schema.org/draft/2019-08/schema#", + "$schema": "https://json-schema.org/draft/2019-08/schema", "$id": "https://json-schema.org/draft/2019-08/meta/format", "$vocabulary": { "https://json-schema.org/draft/2019-08/vocab/format": true diff --git a/meta/hyper-schema.json b/meta/hyper-schema.json index a1d34485..382f4462 100644 --- a/meta/hyper-schema.json +++ b/meta/hyper-schema.json @@ -1,5 +1,5 @@ { - "$schema": "https://json-schema.org/draft/2019-08/hyper-schema#", + "$schema": "https://json-schema.org/draft/2019-08/hyper-schema", "$id": "https://json-schema.org/draft/2019-08/meta/hyper-schema", "$vocabulary": { "https://json-schema.org/draft/2019-08/vocab/hyper-schema": true diff --git a/meta/meta-data.json b/meta/meta-data.json index 20ccf3e7..501cc916 100644 --- a/meta/meta-data.json +++ b/meta/meta-data.json @@ -1,5 +1,5 @@ { - "$schema": "https://json-schema.org/draft/2019-08/schema#", + "$schema": "https://json-schema.org/draft/2019-08/schema", "$id": "https://json-schema.org/draft/2019-08/meta/meta-data", "$vocabulary": { "https://json-schema.org/draft/2019-08/vocab/meta-data": true diff --git a/meta/validation.json b/meta/validation.json index ad8b6d1c..4c821cca 100644 --- a/meta/validation.json +++ b/meta/validation.json @@ -1,5 +1,5 @@ { - "$schema": "https://json-schema.org/draft/2019-08/schema#", + "$schema": "https://json-schema.org/draft/2019-08/schema", "$id": "https://json-schema.org/draft/2019-08/meta/validation", "$vocabulary": { "https://json-schema.org/draft/2019-08/vocab/validation": true diff --git a/output/hyper-schema.json b/output/hyper-schema.json index 307b3f8c..dceeb4d5 100644 --- a/output/hyper-schema.json +++ b/output/hyper-schema.json @@ -1,5 +1,5 @@ { - "$schema": "https://json-schema.org/draft/2019-08/schema#", + "$schema": "https://json-schema.org/draft/2019-08/schema", "$id": "https://json-schema.org/draft/2019-08/output/hyper-schema", "title": "JSON Hyper-Schema Output", "type": "array", diff --git a/output/schema.json b/output/schema.json index e95d8d0b..72a22c6f 100644 --- a/output/schema.json +++ b/output/schema.json @@ -1,5 +1,5 @@ { - "$schema": "https://json-schema.org/draft/2019-08/schema#", + "$schema": "https://json-schema.org/draft/2019-08/schema", "$id": "https://json-schema.org/draft/2019-08/output/schema", "description": "A schema that validates the minimum requirements for validation output", diff --git a/schema.json b/schema.json index daca1a49..80c73c70 100644 --- a/schema.json +++ b/schema.json @@ -1,6 +1,6 @@ { - "$schema": "https://json-schema.org/draft/2019-08/schema#", - "$id": "https://json-schema.org/draft/2019-08/schema#", + "$schema": "https://json-schema.org/draft/2019-08/schema", + "$id": "https://json-schema.org/draft/2019-08/schema", "$vocabulary": { "https://json-schema.org/draft/2019-08/vocab/core": true, "https://json-schema.org/draft/2019-08/vocab/applicator": true,