|
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 |
|
419 | 419 | <t> |
420 | 420 | A JSON Schema resource is a schema which is |
421 | 421 | <xref target="RFC6596">canonically</xref> identified by an |
422 | | - <xref target="RFC3986">absolute URI</xref>. |
| 422 | + <xref target="RFC3986">absolute URI</xref>. Schema resources MAY |
| 423 | + also be identified by URIs including fragments. Any such URIs |
| 424 | + are considered to be non-canonical. |
423 | 425 | </t> |
424 | 426 | <t> |
425 | 427 | The root schema is the schema that comprises the entire JSON document |
|
723 | 725 | be able to support those keywords or vocabularies that contain them. |
724 | 726 | </t> |
725 | 727 | </section> |
726 | | - <section title="Identifiers" anchor="identifiers"> |
| 728 | + <section title="Identifiers"> |
727 | 729 | <t> |
728 | | - Identifiers set the canonical URI of a schema, or affect how such URIs are |
| 730 | + Identifiers define URIs for a schema, or affect how such URIs are |
729 | 731 | resolved in <xref target="references">references</xref>, or both. |
730 | 732 | The Core vocabulary defined in this document defines several |
731 | 733 | identifying keywords, most notably "$id". |
|
1333 | 1335 | <t> |
1334 | 1336 | If present, the value for this keyword MUST be a string, and MUST represent a |
1335 | 1337 | valid <xref target="RFC3986">URI-reference</xref>. This URI-reference |
1336 | | - SHOULD be normalized, and MUST resolve to an |
1337 | | - <xref target="RFC3986">absolute-URI</xref> (without a fragment). Therefore, |
1338 | | - "$id" MUST NOT contain a non-empty fragment, and SHOULD NOT contain an |
1339 | | - empty fragment. |
| 1338 | + SHOULD be normalized, and MUST be semantically equivalent to an |
| 1339 | + <xref target="RFC3986">absolute-URI</xref> (without a fragment). |
1340 | 1340 | </t> |
1341 | 1341 | <t> |
1342 | | - Since an empty fragment in the context of the application/schema+json media |
1343 | | - type refers to the same resource as the base URI without a fragment, |
1344 | | - an implementation MAY normalize a URI ending with an empty fragment by removing |
1345 | | - the fragment. However, schema authors SHOULD NOT rely on this behavior |
1346 | | - across implementations. |
| 1342 | + The application/schema+json media type defines that an absolute-URI |
| 1343 | + identifying a resource and the same URI with an empty fragment |
| 1344 | + appended (which identifies the resource's root schema object) are |
| 1345 | + semantically equivalent. Since this semantic equivalence is not part |
| 1346 | + of the <xref target="RFC3986">RFC 3986 normalization process</xref>, |
| 1347 | + implementors and schema authors cannot rely on generic URI libraries |
| 1348 | + understanding the equivalence. |
| 1349 | + </t> |
| 1350 | + <t> |
| 1351 | + Therefore, "$id" MUST NOT contain a non-empty fragment, and SHOULD NOT |
| 1352 | + contain an empty fragment. The absolute-URI form MUST be considered |
| 1353 | + the canonical URI, regardless of the presence or absence of an empty fragment. |
1347 | 1354 | <cref> |
1348 | | - This is primarily allowed because older meta-schemas have an empty |
1349 | | - fragment in their $id (or previously, id). A future draft may outright |
1350 | | - forbid even empty fragments in "$id". |
| 1355 | + An empty fragment is currently allowed because older meta-schemas have |
| 1356 | + an empty fragment in their $id (or previously, id). |
| 1357 | + A future draft may outright forbid even empty fragments in "$id". |
1351 | 1358 | </cref> |
1352 | 1359 | </t> |
1353 | 1360 | <t> |
1354 | | - This URI also serves as the base URI for relative URI-references in keywords |
1355 | | - within the schema resource, in accordance with |
| 1361 | + The absolute-URI also serves as the base URI for relative URI-references |
| 1362 | + in keywords within the schema resource, in accordance with |
1356 | 1363 | <xref target="RFC3986">RFC 3986 section 5.1.1</xref> regarding base URIs |
1357 | 1364 | embedded in content. |
1358 | 1365 | </t> |
|
1616 | 1623 | media type. |
1617 | 1624 | </t> |
1618 | 1625 | <t> |
1619 | | - Unless the "$id" keyword described in the next section is present in the |
| 1626 | + Unless the "$id" keyword described in an earlier section is present in the |
1620 | 1627 | root schema, this base URI SHOULD be considered the canonical URI of the |
1621 | 1628 | schema document's root schema resource. |
1622 | 1629 | </t> |
|
1743 | 1750 | Since JSON Pointer URI fragments are constructed based on the structure |
1744 | 1751 | of the schema document, an embedded schema resource and its subschemas |
1745 | 1752 | can be identified by JSON Pointer fragments relative to either its own |
1746 | | - canonical URI, or relative to the containing resource's URI. |
| 1753 | + canonical URI, or relative to a containing resource's URI. |
1747 | 1754 | </t> |
1748 | 1755 | <t> |
1749 | 1756 | Conceptually, a set of linked schema resources should behave |
|
1775 | 1782 | } |
1776 | 1783 | ]]> |
1777 | 1784 | </artwork> |
1778 | | - <postamble> |
1779 | | - The URI "https://example.com/foo#/items/additionalProperties" |
1780 | | - points to the schema of the "additionalProperties" keyword in |
1781 | | - the embedded resource. The canonical URI of that schema, however, |
1782 | | - is "https://example.com/bar#/additionalProperties". |
1783 | | - </postamble> |
1784 | 1785 | </figure> |
| 1786 | + <t> |
| 1787 | + The URI "https://example.com/foo#/items" points to the "items" schema, |
| 1788 | + which is an embedded resource. The canonical URI of that schema |
| 1789 | + resource, however, is "https://example.com/bar". |
| 1790 | + </t> |
| 1791 | + <t> |
| 1792 | + For the "additionalProperties" schema within that embedded resource, |
| 1793 | + the URI "https://example.com/foo#/items/additionalProperties" points |
| 1794 | + to the correct object, but that object's URI relative to its resource's |
| 1795 | + canonical URI is "https://example.com/bar#/additionalProperties". |
| 1796 | + </t> |
1785 | 1797 | <figure> |
1786 | 1798 | <preamble> |
1787 | 1799 | Now consider the following two schema resources linked by reference |
|
1803 | 1815 | ]]> |
1804 | 1816 | </artwork> |
1805 | 1817 | <postamble> |
1806 | | - Here we see that the canonical URI for that "additionalProperties" |
1807 | | - subschema is still valid, while the non-canonical URI with the fragment |
1808 | | - beginning with "#/items/$ref" now resolves to nothing. |
| 1818 | + Here we see that the URI for the "additionalProperties" schema object |
| 1819 | + that is relative to its resource's canonical URI is still valid, |
| 1820 | + while the URI relative to the "items" schema object's URI no longer |
| 1821 | + resolves to anything. |
1809 | 1822 | </postamble> |
1810 | 1823 | </figure> |
1811 | 1824 | <t> |
1812 | 1825 | Note also that "https://example.com/foo#/items" is valid in both |
1813 | 1826 | arrangements, but resolves to a different value. This URI ends up |
1814 | | - functioning similarly to a retrieval URI for a resource. While valid, |
1815 | | - examining the resolved value and either using the "$id" (if the value |
1816 | | - is a subschema), or resolving the reference and using the "$id" of the |
1817 | | - reference target, is preferable. |
| 1827 | + functioning similarly to a retrieval URI for a resource. While this URI |
| 1828 | + is valid, it is more robust to use the "$id" of the embedded or referenced |
| 1829 | + resource unless it is specifically desired to identify the object containing |
| 1830 | + the "$ref" in the second (non-embedded) arrangement. |
1818 | 1831 | </t> |
1819 | 1832 | <t> |
1820 | | - An implementation MAY choose not to support addressing schemas |
1821 | | - by non-canonical URIs. As such, it is RECOMMENDED that schema authors only |
1822 | | - use canonical URIs, as using non-canonical URIs may reduce |
1823 | | - schema interoperability. |
| 1833 | + An implementation MAY choose not to support addressing schema resource |
| 1834 | + contents by URIs using a base other than the resource's canonical URI, |
| 1835 | + plus a JSON Pointer fragment relative to that base. Therefore, schema |
| 1836 | + authors SHOULD NOT rely on such URIs, as using them may reduce interoperability. |
1824 | 1837 | <cref> |
1825 | 1838 | This is to avoid requiring implementations to keep track of a whole |
1826 | 1839 | stack of possible base URIs and JSON Pointer fragments for each, |
|
1832 | 1845 | </cref> |
1833 | 1846 | </t> |
1834 | 1847 | <t> |
1835 | | - Further examples of such non-canonical URIs, as well as the appropriate |
1836 | | - canonical URIs to use instead, are provided in appendix |
1837 | | - <xref target="idExamples" format="counter"></xref>. |
| 1848 | + Further examples of such non-canonical URI construction, as well as |
| 1849 | + the appropriate canonical URI-based fragments to use instead, |
| 1850 | + are provided in appendix <xref target="idExamples" format="counter"></xref>. |
1838 | 1851 | </t> |
1839 | 1852 | </section> |
1840 | 1853 | </section> |
|
2695 | 2708 | <section title="Keyword Absolute Location"> |
2696 | 2709 | <t> |
2697 | 2710 | The absolute, dereferenced location of the validating keyword. The value MUST |
2698 | | - be expressed as a full URI using the canonical URI of the relevant |
2699 | | - schema object, and it MUST NOT include by-reference applicators |
| 2711 | + be expressed as a full URI using the canonical URI of the relevant schema resource |
| 2712 | + with a JSON Pointer fragment, and it MUST NOT include by-reference applicators |
2700 | 2713 | such as "$ref" or "$dynamicRef" as non-terminal path components. |
2701 | 2714 | It MAY end in such keywords if the error or annotation is for that |
2702 | 2715 | keyword, such as an unresolvable reference. |
@@ -3332,76 +3345,76 @@ https://example.com/schemas/common#/$defs/count/minimum |
3332 | 3345 | <list style="hanging"> |
3333 | 3346 | <t hangText="# (document root)"> |
3334 | 3347 | <list style="hanging"> |
3335 | | - <t hangText="canonical absolute-URI (and also base URI)"> |
| 3348 | + <t hangText="canonical (and base) URI"> |
3336 | 3349 | https://example.com/root.json |
3337 | 3350 | </t> |
3338 | | - <t hangText="canonical URI with pointer fragment"> |
| 3351 | + <t hangText="canonical resource URI plus pointer fragment"> |
3339 | 3352 | https://example.com/root.json# |
3340 | 3353 | </t> |
3341 | 3354 | </list> |
3342 | 3355 | </t> |
3343 | 3356 | <t hangText="#/$defs/A"> |
3344 | 3357 | <list> |
3345 | 3358 | <t hangText="base URI">https://example.com/root.json</t> |
3346 | | - <t hangText="canonical URI with plain fragment"> |
| 3359 | + <t hangText="canonical resource URI plus plain fragment"> |
3347 | 3360 | https://example.com/root.json#foo |
3348 | 3361 | </t> |
3349 | | - <t hangText="canonical URI with pointer fragment"> |
| 3362 | + <t hangText="canonical resource URI plus pointer fragment"> |
3350 | 3363 | https://example.com/root.json#/$defs/A |
3351 | 3364 | </t> |
3352 | 3365 | </list> |
3353 | 3366 | </t> |
3354 | 3367 | <t hangText="#/$defs/B"> |
3355 | 3368 | <list style="hanging"> |
3356 | | - <t hangText="base URI">https://example.com/other.json</t> |
3357 | | - <t hangText="canonical URI with pointer fragment"> |
| 3369 | + <t hangText="canonical (and base) URI">https://example.com/other.json</t> |
| 3370 | + <t hangText="canonical resource URI plus pointer fragment"> |
3358 | 3371 | https://example.com/other.json# |
3359 | 3372 | </t> |
3360 | | - <t hangText="non-canonical URI with fragment relative to root.json"> |
| 3373 | + <t hangText="base URI of enclosing (root.json) resource plus fragment"> |
3361 | 3374 | https://example.com/root.json#/$defs/B |
3362 | 3375 | </t> |
3363 | 3376 | </list> |
3364 | 3377 | </t> |
3365 | 3378 | <t hangText="#/$defs/B/$defs/X"> |
3366 | 3379 | <list style="hanging"> |
3367 | 3380 | <t hangText="base URI">https://example.com/other.json</t> |
3368 | | - <t hangText="canonical URI with plain fragment"> |
| 3381 | + <t hangText="canonical resource URI plus plain fragment"> |
3369 | 3382 | https://example.com/other.json#bar |
3370 | 3383 | </t> |
3371 | | - <t hangText="canonical URI with pointer fragment"> |
| 3384 | + <t hangText="canonical resource URI plus pointer fragment"> |
3372 | 3385 | https://example.com/other.json#/$defs/X |
3373 | 3386 | </t> |
3374 | | - <t hangText="non-canonical URI with fragment relative to root.json"> |
| 3387 | + <t hangText="base URI of enclosing (root.json) resource plus fragment"> |
3375 | 3388 | https://example.com/root.json#/$defs/B/$defs/X |
3376 | 3389 | </t> |
3377 | 3390 | </list> |
3378 | 3391 | </t> |
3379 | 3392 | <t hangText="#/$defs/B/$defs/Y"> |
3380 | 3393 | <list style="hanging"> |
3381 | | - <t hangText="base URI">https://example.com/t/inner.json</t> |
3382 | | - <t hangText="canonical URI with plain fragment"> |
| 3394 | + <t hangText="canonical (and base) URI">https://example.com/t/inner.json</t> |
| 3395 | + <t hangText="canonical URI plus plain fragment"> |
3383 | 3396 | https://example.com/t/inner.json#bar |
3384 | 3397 | </t> |
3385 | | - <t hangText="canonical URI with pointer fragment"> |
| 3398 | + <t hangText="canonical URI plus pointer fragment"> |
3386 | 3399 | https://example.com/t/inner.json# |
3387 | 3400 | </t> |
3388 | | - <t hangText="non-canonical URI with fragment relative to other.json"> |
| 3401 | + <t hangText="base URI of enclosing (other.json) resource plus fragment"> |
3389 | 3402 | https://example.com/other.json#/$defs/Y |
3390 | 3403 | </t> |
3391 | | - <t hangText="non-canonical URI with fragment relative to root.json"> |
| 3404 | + <t hangText="base URI of enclosing (root.json) resource plus fragment"> |
3392 | 3405 | https://example.com/root.json#/$defs/B/$defs/Y |
3393 | 3406 | </t> |
3394 | 3407 | </list> |
3395 | 3408 | </t> |
3396 | 3409 | <t hangText="#/$defs/C"> |
3397 | 3410 | <list style="hanging"> |
3398 | | - <t hangText="base URI"> |
| 3411 | + <t hangText="canonical (and base) URI"> |
3399 | 3412 | urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f |
3400 | 3413 | </t> |
3401 | | - <t hangText="canonical URI with pointer fragment"> |
| 3414 | + <t hangText="canonical URI plus pointer fragment"> |
3402 | 3415 | urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f# |
3403 | 3416 | </t> |
3404 | | - <t hangText="non-canonical URI with fragment relative to root.json"> |
| 3417 | + <t hangText="base URI of enclosing (root.json) resource plus fragment"> |
3405 | 3418 | https://example.com/root.json#/$defs/C |
3406 | 3419 | </t> |
3407 | 3420 | </list> |
@@ -3433,16 +3446,16 @@ https://example.com/schemas/common#/$defs/count/minimum |
3433 | 3446 | <t> |
3434 | 3447 | This transformation can be safely and reversibly done as long as |
3435 | 3448 | all static references (e.g. "$ref") use URI-references that resolve |
3436 | | - to canonical URIs, and all schema resources have an absolute-URI |
3437 | | - as the "$id" in their root schema. |
| 3449 | + to URIs using the canonical resource URI as the base, and all schema |
| 3450 | + resources have an absolute-URI as the "$id" in their root schema. |
3438 | 3451 | </t> |
3439 | 3452 | <t> |
3440 | 3453 | With these conditions met, each external resource can be copied |
3441 | 3454 | under "$defs", without breaking any references among the resources' |
3442 | 3455 | schema objects, and without changing any aspect of validation or |
3443 | 3456 | annotation results. The names of the schemas under "$defs" do |
3444 | 3457 | not affect behavior, assuming they are each unique, as they |
3445 | | - do not appear in canonical URIs for the embedded resources. |
| 3458 | + do not appear in the canonical URIs for the embedded resources. |
3446 | 3459 | </t> |
3447 | 3460 | </section> |
3448 | 3461 | <section title="Reference removal is not always safe"> |
|
0 commit comments