|
315 | 315 | of five categories:
|
316 | 316 | <list style="hanging">
|
317 | 317 | <t hangText="identifiers:">
|
318 |
| - control schema identification through setting the schema's |
319 |
| - canonical URI and/or changing how the base URI is determined |
| 318 | + control schema identification through setting a URI |
| 319 | + for the schema and/or changing how the base URI is determined |
320 | 320 | </t>
|
321 | 321 | <t hangText="assertions:">
|
322 | 322 | produce a boolean result when applied to an instance
|
|
426 | 426 | <t>
|
427 | 427 | A JSON Schema resource is a schema which is
|
428 | 428 | <xref target="RFC6596">canonically</xref> identified by an
|
429 |
| - <xref target="RFC3986">absolute URI</xref>. |
| 429 | + <xref target="RFC3986">absolute URI</xref>. Schema resources MAY |
| 430 | + also be identified by URIs including fragments. Any such URIs |
| 431 | + are considered to be non-canonical. |
430 | 432 | </t>
|
431 | 433 | <t>
|
432 | 434 | The root schema is the schema that comprises the entire JSON document
|
|
730 | 732 | be able to support those keywords or vocabularies that contain them.
|
731 | 733 | </t>
|
732 | 734 | </section>
|
733 |
| - <section title="Identifiers" anchor="identifiers"> |
| 735 | + <section title="Identifiers"> |
734 | 736 | <t>
|
735 |
| - Identifiers set the canonical URI of a schema, or affect how such URIs are |
| 737 | + Identifiers define URIs for a schema, or affect how such URIs are |
736 | 738 | resolved in <xref target="references">references</xref>, or both.
|
737 | 739 | The Core vocabulary defined in this document defines several
|
738 | 740 | identifying keywords, most notably "$id".
|
|
1340 | 1342 | <t>
|
1341 | 1343 | If present, the value for this keyword MUST be a string, and MUST represent a
|
1342 | 1344 | valid <xref target="RFC3986">URI-reference</xref>. This URI-reference
|
1343 |
| - SHOULD be normalized, and MUST resolve to an |
1344 |
| - <xref target="RFC3986">absolute-URI</xref> (without a fragment). Therefore, |
1345 |
| - "$id" MUST NOT contain a non-empty fragment, and SHOULD NOT contain an |
1346 |
| - empty fragment. |
| 1345 | + SHOULD be normalized, and MUST be semantically equivalent to an |
| 1346 | + <xref target="RFC3986">absolute-URI</xref> (without a fragment). |
1347 | 1347 | </t>
|
1348 | 1348 | <t>
|
1349 |
| - Since an empty fragment in the context of the application/schema+json media |
1350 |
| - type refers to the same resource as the base URI without a fragment, |
1351 |
| - an implementation MAY normalize a URI ending with an empty fragment by removing |
1352 |
| - the fragment. However, schema authors SHOULD NOT rely on this behavior |
1353 |
| - across implementations. |
| 1349 | + The application/schema+json media type defines that an absolute-URI |
| 1350 | + identifying a resource and the same URI with an empty fragment |
| 1351 | + appended (which identifies the resource's root schema object) are |
| 1352 | + semantically equivalent. Since this semantic equivalence is not part |
| 1353 | + of the <xref target="RFC3986">RFC 3986 normalization process</xref>, |
| 1354 | + implementors and schema authors cannot rely on generic URI libraries |
| 1355 | + understanding the equivalence. |
| 1356 | + </t> |
| 1357 | + <t> |
| 1358 | + Therefore, "$id" MUST NOT contain a non-empty fragment, and SHOULD NOT |
| 1359 | + contain an empty fragment. The absolute-URI form MUST be considered |
| 1360 | + the canonical URI, regardless of the presence or absence of an empty fragment. |
1354 | 1361 | <cref>
|
1355 |
| - This is primarily allowed because older meta-schemas have an empty |
1356 |
| - fragment in their $id (or previously, id). A future draft may outright |
1357 |
| - forbid even empty fragments in "$id". |
| 1362 | + An empty fragment is currently allowed because older meta-schemas have |
| 1363 | + an empty fragment in their $id (or previously, id). |
| 1364 | + A future draft may outright forbid even empty fragments in "$id". |
1358 | 1365 | </cref>
|
1359 | 1366 | </t>
|
1360 | 1367 | <t>
|
1361 |
| - This URI also serves as the base URI for relative URI-references in keywords |
1362 |
| - within the schema resource, in accordance with |
| 1368 | + The absolute-URI also serves as the base URI for relative URI-references |
| 1369 | + in keywords within the schema resource, in accordance with |
1363 | 1370 | <xref target="RFC3986">RFC 3986 section 5.1.1</xref> regarding base URIs
|
1364 | 1371 | embedded in content.
|
1365 | 1372 | </t>
|
|
1623 | 1630 | media type.
|
1624 | 1631 | </t>
|
1625 | 1632 | <t>
|
1626 |
| - Unless the "$id" keyword described in the next section is present in the |
| 1633 | + Unless the "$id" keyword described in an earlier section is present in the |
1627 | 1634 | root schema, this base URI SHOULD be considered the canonical URI of the
|
1628 | 1635 | schema document's root schema resource.
|
1629 | 1636 | </t>
|
|
1750 | 1757 | Since JSON Pointer URI fragments are constructed based on the structure
|
1751 | 1758 | of the schema document, an embedded schema resource and its subschemas
|
1752 | 1759 | can be identified by JSON Pointer fragments relative to either its own
|
1753 |
| - canonical URI, or relative to the containing resource's URI. |
| 1760 | + canonical URI, or relative to a containing resource's URI. |
1754 | 1761 | </t>
|
1755 | 1762 | <t>
|
1756 | 1763 | Conceptually, a set of linked schema resources should behave
|
|
1782 | 1789 | }
|
1783 | 1790 | ]]>
|
1784 | 1791 | </artwork>
|
1785 |
| - <postamble> |
1786 |
| - The URI "https://example.com/foo#/items/additionalProperties" |
1787 |
| - points to the schema of the "additionalProperties" keyword in |
1788 |
| - the embedded resource. The canonical URI of that schema, however, |
1789 |
| - is "https://example.com/bar#/additionalProperties". |
1790 |
| - </postamble> |
1791 | 1792 | </figure>
|
| 1793 | + <t> |
| 1794 | + The URI "https://example.com/foo#/items" points to the "items" schema, |
| 1795 | + which is an embedded resource. The canonical URI of that schema |
| 1796 | + resource, however, is "https://example.com/bar". |
| 1797 | + </t> |
| 1798 | + <t> |
| 1799 | + For the "additionalProperties" schema within that embedded resource, |
| 1800 | + the URI "https://example.com/foo#/items/additionalProperties" points |
| 1801 | + to the correct object, but that object's URI relative to its resource's |
| 1802 | + canonical URI is "https://example.com/bar#/additionalProperties". |
| 1803 | + </t> |
1792 | 1804 | <figure>
|
1793 | 1805 | <preamble>
|
1794 | 1806 | Now consider the following two schema resources linked by reference
|
|
1810 | 1822 | ]]>
|
1811 | 1823 | </artwork>
|
1812 | 1824 | <postamble>
|
1813 |
| - Here we see that the canonical URI for that "additionalProperties" |
1814 |
| - subschema is still valid, while the non-canonical URI with the fragment |
1815 |
| - beginning with "#/items/$ref" now resolves to nothing. |
| 1825 | + Here we see that the URI for the "additionalProperties" schema object |
| 1826 | + that is relative to its resource's canonical URI is still valid, |
| 1827 | + while the URI relative to the "items" schema object's URI no longer |
| 1828 | + resolves to anything. |
1816 | 1829 | </postamble>
|
1817 | 1830 | </figure>
|
1818 | 1831 | <t>
|
1819 | 1832 | Note also that "https://example.com/foo#/items" is valid in both
|
1820 | 1833 | arrangements, but resolves to a different value. This URI ends up
|
1821 |
| - functioning similarly to a retrieval URI for a resource. While valid, |
1822 |
| - examining the resolved value and either using the "$id" (if the value |
1823 |
| - is a subschema), or resolving the reference and using the "$id" of the |
1824 |
| - reference target, is preferable. |
| 1834 | + functioning similarly to a retrieval URI for a resource. While this URI |
| 1835 | + is valid, it is more robust to use the "$id" of the embedded or referenced |
| 1836 | + resource unless it is specifically desired to identify the object containing |
| 1837 | + the "$ref" in the second (non-embedded) arrangement. |
1825 | 1838 | </t>
|
1826 | 1839 | <t>
|
1827 |
| - An implementation MAY choose not to support addressing schemas |
1828 |
| - by non-canonical URIs. As such, it is RECOMMENDED that schema authors only |
1829 |
| - use canonical URIs, as using non-canonical URIs may reduce |
1830 |
| - schema interoperability. |
| 1840 | + An implementation MAY choose not to support addressing schema resource |
| 1841 | + contents by URIs using a base other than the resource's canonical URI, |
| 1842 | + plus a JSON Pointer fragment relative to that base. Therefore, schema |
| 1843 | + authors SHOULD NOT rely on such URIs, as using them may reduce interoperability. |
1831 | 1844 | <cref>
|
1832 | 1845 | This is to avoid requiring implementations to keep track of a whole
|
1833 | 1846 | stack of possible base URIs and JSON Pointer fragments for each,
|
|
1839 | 1852 | </cref>
|
1840 | 1853 | </t>
|
1841 | 1854 | <t>
|
1842 |
| - Further examples of such non-canonical URIs, as well as the appropriate |
1843 |
| - canonical URIs to use instead, are provided in appendix |
1844 |
| - <xref target="idExamples" format="counter"></xref>. |
| 1855 | + Further examples of such non-canonical URI construction, as well as |
| 1856 | + the appropriate canonical URI-based fragments to use instead, |
| 1857 | + are provided in appendix <xref target="idExamples" format="counter"></xref>. |
1845 | 1858 | </t>
|
1846 | 1859 | </section>
|
1847 | 1860 | </section>
|
|
2704 | 2717 | <section title="Keyword Absolute Location">
|
2705 | 2718 | <t>
|
2706 | 2719 | The absolute, dereferenced location of the validating keyword. The value MUST
|
2707 |
| - be expressed as a full URI using the canonical URI of the relevant |
2708 |
| - schema object, and it MUST NOT include by-reference applicators |
| 2720 | + be expressed as a full URI using the canonical URI of the relevant schema resource |
| 2721 | + with a JSON Pointer fragment, and it MUST NOT include by-reference applicators |
2709 | 2722 | such as "$ref" or "$dynamicRef" as non-terminal path components.
|
2710 | 2723 | It MAY end in such keywords if the error or annotation is for that
|
2711 | 2724 | keyword, such as an unresolvable reference.
|
@@ -3314,76 +3327,76 @@ https://example.com/schemas/common#/$defs/count/minimum
|
3314 | 3327 | <list style="hanging">
|
3315 | 3328 | <t hangText="# (document root)">
|
3316 | 3329 | <list style="hanging">
|
3317 |
| - <t hangText="canonical absolute-URI (and also base URI)"> |
| 3330 | + <t hangText="canonical (and base) URI"> |
3318 | 3331 | https://example.com/root.json
|
3319 | 3332 | </t>
|
3320 |
| - <t hangText="canonical URI with pointer fragment"> |
| 3333 | + <t hangText="canonical resource URI plus pointer fragment"> |
3321 | 3334 | https://example.com/root.json#
|
3322 | 3335 | </t>
|
3323 | 3336 | </list>
|
3324 | 3337 | </t>
|
3325 | 3338 | <t hangText="#/$defs/A">
|
3326 | 3339 | <list>
|
3327 | 3340 | <t hangText="base URI">https://example.com/root.json</t>
|
3328 |
| - <t hangText="canonical URI with plain fragment"> |
| 3341 | + <t hangText="canonical resource URI plus plain fragment"> |
3329 | 3342 | https://example.com/root.json#foo
|
3330 | 3343 | </t>
|
3331 |
| - <t hangText="canonical URI with pointer fragment"> |
| 3344 | + <t hangText="canonical resource URI plus pointer fragment"> |
3332 | 3345 | https://example.com/root.json#/$defs/A
|
3333 | 3346 | </t>
|
3334 | 3347 | </list>
|
3335 | 3348 | </t>
|
3336 | 3349 | <t hangText="#/$defs/B">
|
3337 | 3350 | <list style="hanging">
|
3338 |
| - <t hangText="base URI">https://example.com/other.json</t> |
3339 |
| - <t hangText="canonical URI with pointer fragment"> |
| 3351 | + <t hangText="canonical (and base) URI">https://example.com/other.json</t> |
| 3352 | + <t hangText="canonical resource URI plus pointer fragment"> |
3340 | 3353 | https://example.com/other.json#
|
3341 | 3354 | </t>
|
3342 |
| - <t hangText="non-canonical URI with fragment relative to root.json"> |
| 3355 | + <t hangText="base URI of enclosing (root.json) resource plus fragment"> |
3343 | 3356 | https://example.com/root.json#/$defs/B
|
3344 | 3357 | </t>
|
3345 | 3358 | </list>
|
3346 | 3359 | </t>
|
3347 | 3360 | <t hangText="#/$defs/B/$defs/X">
|
3348 | 3361 | <list style="hanging">
|
3349 | 3362 | <t hangText="base URI">https://example.com/other.json</t>
|
3350 |
| - <t hangText="canonical URI with plain fragment"> |
| 3363 | + <t hangText="canonical resource URI plus plain fragment"> |
3351 | 3364 | https://example.com/other.json#bar
|
3352 | 3365 | </t>
|
3353 |
| - <t hangText="canonical URI with pointer fragment"> |
| 3366 | + <t hangText="canonical resource URI plus pointer fragment"> |
3354 | 3367 | https://example.com/other.json#/$defs/X
|
3355 | 3368 | </t>
|
3356 |
| - <t hangText="non-canonical URI with fragment relative to root.json"> |
| 3369 | + <t hangText="base URI of enclosing (root.json) resource plus fragment"> |
3357 | 3370 | https://example.com/root.json#/$defs/B/$defs/X
|
3358 | 3371 | </t>
|
3359 | 3372 | </list>
|
3360 | 3373 | </t>
|
3361 | 3374 | <t hangText="#/$defs/B/$defs/Y">
|
3362 | 3375 | <list style="hanging">
|
3363 |
| - <t hangText="base URI">https://example.com/t/inner.json</t> |
3364 |
| - <t hangText="canonical URI with plain fragment"> |
| 3376 | + <t hangText="canonical (and base) URI">https://example.com/t/inner.json</t> |
| 3377 | + <t hangText="canonical URI plus plain fragment"> |
3365 | 3378 | https://example.com/t/inner.json#bar
|
3366 | 3379 | </t>
|
3367 |
| - <t hangText="canonical URI with pointer fragment"> |
| 3380 | + <t hangText="canonical URI plus pointer fragment"> |
3368 | 3381 | https://example.com/t/inner.json#
|
3369 | 3382 | </t>
|
3370 |
| - <t hangText="non-canonical URI with fragment relative to other.json"> |
| 3383 | + <t hangText="base URI of enclosing (other.json) resource plus fragment"> |
3371 | 3384 | https://example.com/other.json#/$defs/Y
|
3372 | 3385 | </t>
|
3373 |
| - <t hangText="non-canonical URI with fragment relative to root.json"> |
| 3386 | + <t hangText="base URI of enclosing (root.json) resource plus fragment"> |
3374 | 3387 | https://example.com/root.json#/$defs/B/$defs/Y
|
3375 | 3388 | </t>
|
3376 | 3389 | </list>
|
3377 | 3390 | </t>
|
3378 | 3391 | <t hangText="#/$defs/C">
|
3379 | 3392 | <list style="hanging">
|
3380 |
| - <t hangText="base URI"> |
| 3393 | + <t hangText="canonical (and base) URI"> |
3381 | 3394 | urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f
|
3382 | 3395 | </t>
|
3383 |
| - <t hangText="canonical URI with pointer fragment"> |
| 3396 | + <t hangText="canonical URI plus pointer fragment"> |
3384 | 3397 | urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f#
|
3385 | 3398 | </t>
|
3386 |
| - <t hangText="non-canonical URI with fragment relative to root.json"> |
| 3399 | + <t hangText="base URI of enclosing (root.json) resource plus fragment"> |
3387 | 3400 | https://example.com/root.json#/$defs/C
|
3388 | 3401 | </t>
|
3389 | 3402 | </list>
|
@@ -3415,16 +3428,16 @@ https://example.com/schemas/common#/$defs/count/minimum
|
3415 | 3428 | <t>
|
3416 | 3429 | This transformation can be safely and reversibly done as long as
|
3417 | 3430 | all static references (e.g. "$ref") use URI-references that resolve
|
3418 |
| - to canonical URIs, and all schema resources have an absolute-URI |
3419 |
| - as the "$id" in their root schema. |
| 3431 | + to URIs using the canonical resource URI as the base, and all schema |
| 3432 | + resources have an absolute-URI as the "$id" in their root schema. |
3420 | 3433 | </t>
|
3421 | 3434 | <t>
|
3422 | 3435 | With these conditions met, each external resource can be copied
|
3423 | 3436 | under "$defs", without breaking any references among the resources'
|
3424 | 3437 | schema objects, and without changing any aspect of validation or
|
3425 | 3438 | annotation results. The names of the schemas under "$defs" do
|
3426 | 3439 | not affect behavior, assuming they are each unique, as they
|
3427 |
| - do not appear in canonical URIs for the embedded resources. |
| 3440 | + do not appear in the canonical URIs for the embedded resources. |
3428 | 3441 | </t>
|
3429 | 3442 | </section>
|
3430 | 3443 | <section title="Reference removal is not always safe">
|
|
0 commit comments