Skip to content

Commit 7db77ac

Browse files
committed
More consistent concept of schema resources
This further clarifies the schema resource concept and how it is used. It provides an example to simplify the explanation of how non-canonical URIs can be problematic. This also relaxes a restriction on "$schema" that has no functional impact but avoids requiring implementations to detect and handle a rather complex case (embedding schema resources with different "$schema" values). And also means that embedding can work without having to change the embedded value by removing the "$schema" keyword. Additional best practices for embedding will follow in a separate commit.
1 parent 2da139a commit 7db77ac

File tree

1 file changed

+94
-40
lines changed

1 file changed

+94
-40
lines changed

jsonschema-core.xml

Lines changed: 94 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -409,11 +409,6 @@
409409
<xref target="RFC6596">canonically</xref> identified by an
410410
<xref target="RFC3986">absolute URI</xref>.
411411
</t>
412-
<t>
413-
As discussed in section
414-
<xref target="id-keyword" format="counter"></xref>, a JSON Schema document
415-
can contain multiple JSON Schema resources.
416-
</t>
417412
<t>
418413
The root schema is the schema that comprises the entire JSON document
419414
in question. The root schema is always a schema resource, where the
@@ -442,6 +437,15 @@
442437
<t>
443438
As with the root schema, a subschema is either an object or a boolean.
444439
</t>
440+
<t>
441+
As discussed in section
442+
<xref target="id-keyword" format="counter"></xref>, a JSON Schema document
443+
can contain multiple JSON Schema resources. When used without qualification,
444+
the term "root schema" refers to the document's root schema. In some
445+
cases, resource root schemas are discussed. A resource's root schema
446+
is its top-level schema object, which would also be a document root schema
447+
if the resource were to be extracted to a standalone JSON Schema document.
448+
</t>
445449
</section>
446450
</section>
447451

@@ -624,7 +628,7 @@
624628
<t>
625629
Note that some keywords, such as "$schema", apply to the lexical
626630
scope of the entire schema document, and therefore MUST only
627-
appear in the document's root schema.
631+
appear in a schema resource's root schema.
628632
</t>
629633
<t>
630634
Other keywords may take into account the dynamic scope that
@@ -1131,11 +1135,15 @@
11311135
media type "application/schema+json".
11321136
</t>
11331137
<t>
1134-
The "$schema" keyword SHOULD be used in a root schema.
1135-
It MUST NOT appear in subschemas. If absent from the root schema, the
1138+
The "$schema" keyword SHOULD be used in a resource root schema.
1139+
It MUST NOT appear in resource subschemas. If absent from the root schema, the
11361140
resulting behavior is implementation-defined.
11371141
</t>
11381142
<t>
1143+
If multiple schema resources are present in a single document, then all
1144+
schema resources SHOULD Have the same value for "$schema". The result of
1145+
differing values for "$schema" within the same schema document is
1146+
implementation-defined.
11391147
<cref>
11401148
Using multiple "$schema" keywords in the same document would imply that the
11411149
feature set and therefore behavior can change within a document. This would
@@ -1145,6 +1153,12 @@
11451153
implementation behavior is subject to be revised or liberalized in
11461154
future drafts.
11471155
</cref>
1156+
<cref>
1157+
The exception made for embedded schema resources is to
1158+
allow bundling multiple schema resources into a single schema document
1159+
without needing to change their contents, as described later in this
1160+
specification.
1161+
</cref>
11481162
<!--
11491163
In particular, the process of validating an instance, including validating a
11501164
schema as an instance against its meta-schema, only allows for a single set
@@ -1566,25 +1580,11 @@
15661580
canonical URI, or relative to the containing resource's URI.
15671581
</t>
15681582
<t>
1569-
Conceptually, a set of linked schemas should behave identically whether
1570-
each schema is a separate document connected with
1583+
Conceptually, a set of linked schema resources should behave
1584+
identically whether each resource is a separate document connected with
15711585
<xref target="references">schema references</xref>, or is structured as
15721586
a single document with one or more schema resources embedded as
15731587
subschemas.
1574-
<cref>
1575-
Note that when using schema references, the reference keyword
1576-
appears in the runtime path in the standard output format for
1577-
errors and annotations. This means that while the validation
1578-
outcome is unchanged when switching between an embedded schema
1579-
resource and a referenced one, the runtime paths of annotations
1580-
do change. A future draft may allow directly replacing the value
1581-
of the reference keyword with its target while leaving the keyword
1582-
itself in place in order to make embedding vs referencing transparent
1583-
to annotation collection. This would allow replacing
1584-
{"$ref": "/foo"} with {"$ref": {"type": "string"}}, assuming
1585-
the schema at "verb">"/foo" consists of just a "type" keyword with
1586-
value "string". Feedback on this topic is highly encouraged.
1587-
</cref>
15881588
</t>
15891589
<t>
15901590
Since URIs involving JSON Pointer fragments relative to the parent
@@ -1593,22 +1593,78 @@
15931593
SHOULD NOT use such URIs to identify embedded schema resources or
15941594
locations within them.
15951595
</t>
1596+
<figure>
1597+
<preamble>
1598+
Consider the following schema document that contains another
1599+
schema resource embedded within it:
1600+
</preamble>
1601+
<artwork>
1602+
<![CDATA[
1603+
{
1604+
"$id": "https://example.com/foo",
1605+
"items": {
1606+
"$id": "https://example.com/bar",
1607+
"additionalProperties": { }
1608+
}
1609+
}
1610+
]]>
1611+
</artwork>
1612+
<postamble>
1613+
The URI "https://example.com/foo#/items/additionalProperties"
1614+
points to the schema of the "additionalProperties" keyword in
1615+
the embedded resource. The canonical URI of that schema, however,
1616+
is "https://example.com/bar#/additionalProperties".
1617+
</postamble>
1618+
</figure>
1619+
<figure>
1620+
<preamble>
1621+
Now consider the following two schema resources linked by reference
1622+
using a URI value for "$ref":
1623+
</preamble>
1624+
<artwork>
1625+
<![CDATA[
1626+
{
1627+
"$id": "https://example.com/foo",
1628+
"items": {
1629+
"$ref": "bar"
1630+
}
1631+
}
1632+
1633+
{
1634+
"$id": "https://example.com/bar",
1635+
"additionalProperties": { }
1636+
}
1637+
]]>
1638+
</artwork>
1639+
<postamble>
1640+
Here we see that the canonical URI for that "additionalProperties"
1641+
subschema is still valid, while the non-canonical URI with the fragment
1642+
beginning with "#/items/$ref" now resolves to nothing.
1643+
</postamble>
1644+
</figure>
1645+
<t>
1646+
Note also that "https://example.com/foo#/items" is valid in both
1647+
arrangments, but resolves to a different value. This URI ends up
1648+
functioning similarly to a retrieval URI for a resource. While valid,
1649+
examining the resolved value and either using the "$id" (if the value
1650+
is a subschema), or resolving the reference and using the "$id" of the
1651+
reference target, is preferable.
1652+
</t>
15961653
<t>
1597-
Using such URIs is unreliable, and an implementation MAY choose not to
1598-
support them. If an embedded schema were to be replaced with a reference,
1599-
then the JSON Pointer fragment URI for that schema relative to its
1600-
parent's base URI would then identify the reference, while JSON Pointers
1601-
to locations within the formerly embedded resource would become invalid.
1654+
An implementation MAY choose not to support addressing schemas
1655+
by non-canonical URIs.
16021656
<cref>
1603-
If the change regarding reference replacement noted in the previous
1604-
CREF were to be implemented, the pointer behavior would be more
1605-
consistent. Really it is the pointers to deeper locations within
1606-
embedded schemas which should be strongly discouraged and
1607-
need not be supported.
1657+
This is to avoid requiring implementations to keep track of a whole
1658+
stack of possible base URIs and JSON Pointer fragments for each,
1659+
given that all but one will be fragile if the schema resources
1660+
are reorganized. Some have argued that this is easy so there is
1661+
no point in forbidding it, while others have argued that it complicates
1662+
schema identification and should be forbidden. Feedback on this
1663+
topic is encouraged.
16081664
</cref>
16091665
</t>
16101666
<t>
1611-
Examples of such non-canonical URIs, as well as the appropriate
1667+
Further examples of such non-canonical URIs, as well as the appropriate
16121668
canonical URIs to use instead, are provided in section
16131669
<xref target="idExamples" format="counter"></xref>.
16141670
</t>
@@ -1792,11 +1848,9 @@
17921848
<section title='Direct References with "$ref"' anchor="ref">
17931849
<t>
17941850
The "$ref" keyword is used to reference a statically identified schema.
1795-
</t>
1796-
<t>
1797-
The value of the "$ref" property MUST be a string which is a URI Reference.
1798-
Resolved against the current URI base, it identifies the URI of a schema
1799-
to use.
1851+
The value of the "$ref" property MUST be a string which is a URI-Reference.
1852+
Resolved against the current URI base, it produces the URI of the schema
1853+
to apply.
18001854
</t>
18011855
</section>
18021856

0 commit comments

Comments
 (0)