Skip to content
This repository was archived by the owner on Nov 2, 2023. It is now read-only.

Commit 98e84dc

Browse files
committed
Update review copy for anchor example
1 parent bf67ba2 commit 98e84dc

File tree

1 file changed

+74
-19
lines changed

1 file changed

+74
-19
lines changed

work-in-progress/WIP-jsonschema-hyperschema.html

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@
429429
<link href="#rfc.section.9.1" rel="Chapter" title="9.1 Entry point links, no templates"/>
430430
<link href="#rfc.section.9.2" rel="Chapter" title="9.2 Individually identified resources"/>
431431
<link href="#rfc.section.9.3" rel="Chapter" title="9.3 Submitting a payload and accepting URI input"/>
432-
<link href="#rfc.section.9.4" rel="Chapter" title="9.4 &quot;anchor&quot; and &quot;base&quot; as URI Templates"/>
432+
<link href="#rfc.section.9.4" rel="Chapter" title="9.4 &quot;anchor&quot;, &quot;base&quot; and URI Template resolution"/>
433433
<link href="#rfc.section.9.5" rel="Chapter" title="9.5 Collections"/>
434434
<link href="#rfc.section.10" rel="Chapter" title="10 Security Considerations"/>
435435
<link href="#rfc.section.10.1" rel="Chapter" title="10.1 &quot;self&quot; links"/>
@@ -569,7 +569,7 @@ <h1 class="np" id="rfc.toc"><a href="#rfc.toc">Table of Contents</a></h1>
569569
<ul><li>9.1. <a href="#rfc.section.9.1">Entry point links, no templates</a></li>
570570
<li>9.2. <a href="#rfc.section.9.2">Individually identified resources</a></li>
571571
<li>9.3. <a href="#rfc.section.9.3">Submitting a payload and accepting URI input</a></li>
572-
<li>9.4. <a href="#rfc.section.9.4">"anchor" and "base" as URI Templates</a></li>
572+
<li>9.4. <a href="#rfc.section.9.4">"anchor", "base" and URI Template resolution</a></li>
573573
<li>9.5. <a href="#rfc.section.9.5">Collections</a></li>
574574
</ul><li>10. <a href="#rfc.section.10">Security Considerations</a></li>
575575
<ul><li>10.1. <a href="#rfc.section.10.1">"self" links</a></li>
@@ -1129,7 +1129,7 @@ <h1 id="rfc.section.9.3"><a href="#rfc.section.9.3">9.3.</a> Submitting a payloa
11291129
},
11301130
"email": false
11311131
}
1132-
}
1132+
},
11331133
"submissionMediaType":
11341134
"multipart/alternative; boundary=ab2",
11351135
"submissionSchema": {
@@ -1186,17 +1186,70 @@ <h1 id="rfc.section.9.3"><a href="#rfc.section.9.3">9.3.</a> Submitting a payloa
11861186
</dl>
11871187

11881188
<p> </p>
1189-
<h1 id="rfc.section.9.4"><a href="#rfc.section.9.4">9.4.</a> "anchor" and "base" as URI Templates</h1>
1190-
<p>
1191-
<a id="CREF8" class="info">[CREF8]<span class="info">"base" used as a template with both "anchor" and "href" templates. </span></a>
1192-
</p>
1189+
<h1 id="rfc.section.9.4"><a href="#rfc.section.9.4">9.4.</a> "anchor", "base" and URI Template resolution</h1>
1190+
<p id="rfc.section.9.4.p.1">A link is a typed connection from a context resource to a target resource. Older link serializations support a "rev" keyword that takes a link relation type as "rel" does, but reverses the semantics. This has long been deprecated, so JSON Hyper-Schema does not support it. Instead, "anchor"'s ability to change the context URI can be used to reverse the direction of a link. It can also be used to describe a link between two resources, neither of which is the current resource. </p>
1191+
<p id="rfc.section.9.4.p.2">As an example, there is an IANA-registered "up" relation, but there is no "down". In an HTTP Link header, you could implement "down" as <samp>"rev": "up"</samp>. </p>
1192+
<p>First let's look at how this could be done in HTTP, showing a "self" link and two semantically identical links, one with "rev": "up" and the other using "anchor" with "rel": "up" (line wrapped due to formatting limitations). </p>
1193+
<pre>
1194+
1195+
GET https://api.example.com/trees/1/nodes/123 HTTP/1.1
1196+
1197+
200 OK
1198+
Content-Type: application/json
1199+
Link: &lt;https://api.example.com/trees/1/nodes/123&gt; rel=self
1200+
Link: &lt;https://api.example.com/trees/1/nodes/123&gt; rel=up
1201+
anchor=&lt;https://api.example.com/trees/1/nodes/456&gt;
1202+
Link: &lt;https://api.example.com/trees/1/nodes/456&gt; rev=up
1203+
{
1204+
"id": 123
1205+
"treeId": 1,
1206+
"childIds": [456]
1207+
}
1208+
1209+
</pre>
1210+
<p>Note that the "rel=up" link has a target URI identical to the "rel=self" link, and sets "anchor" (which identifies the link's context) to the child's URI. This sort of reversed link is easily detectable by tools when a "self" link is also present. </p>
1211+
<p>The following hyper-schema, applied to the instance in the response above, would produce the same "self" link and "up" link with "anchor". It also shows the use of a templated "base" URI, plus both absolute and relative JSON Pointers in "tempaltePointers". </p>
1212+
<pre>
1213+
1214+
"base": "trees/{treeId}",
1215+
"properties": {
1216+
"id": {"type": "integer"},
1217+
"treeId": {"type": "integer"},
1218+
"childIds": {
1219+
"type": "array",
1220+
"items": {
1221+
"type": "integer",
1222+
"links": [
1223+
{
1224+
"anchor": "nodes/{thisNodeId}",
1225+
"rel": "up",
1226+
"href": "nodes/{childId}",
1227+
"templatePointers": {
1228+
"thisNodeId": "/id",
1229+
"childId": "0"
1230+
}
1231+
}
1232+
]
1233+
}
1234+
}
1235+
},
1236+
"links": [
1237+
{
1238+
"rel": "self",
1239+
"href": "nodes/{id}"
1240+
}
1241+
]
1242+
}
1243+
</pre>
1244+
<p>The "base" template is evaluated identically for both the target ("href") and context ("anchor") URIs. </p>
1245+
<p id="rfc.section.9.4.p.3">Note the two different sorts of templatePointers used. "thisNodeId" is mapped to an absolute JSON Pointer, "/id", while "childId" is mapped to a relative pointer, "0", which indicates the value of the current item. Absolute JSON Pointers do not support any kind of wildcarding, so there is no way to specify a concept like "current item" without a relative JSON Pointer. </p>
11931246
<h1 id="rfc.section.9.5"><a href="#rfc.section.9.5">9.5.</a> Collections</h1>
11941247
<p>
1195-
<a id="CREF9" class="info">[CREF9]<span class="info">Reciprocal collection/item relations Pagination: fixed links vs jumping to an arbitrary offset Using "anchorPointer" and "templatePointers" Discovering ordered links Multiple self links (for the collection and each item) </span></a>
1248+
<a id="CREF8" class="info">[CREF8]<span class="info">Reciprocal collection/item relations Pagination: fixed links vs jumping to an arbitrary offset Using "anchorPointer" and "templatePointers" Discovering ordered links Multiple self links (for the collection and each item) </span></a>
11961249
</p>
11971250
<p id="rfc.section.9.5.p.2">In many systems, individual resources are grouped into collections. Those collections also often provide a way to create individual item resources with server-assigned identifiers. </p>
11981251
<p id="rfc.section.9.5.p.3">This schema describes a collection where each item representation is identical to the individual resource item representation, and there is enough metadata included in the collection representation to produce pagination links. The "first" and "last" pagination links were omitted as this is already a long example. </p>
1199-
<p id="rfc.section.9.5.p.4">Note that there is an object member called "items", which is an array and thefore uses the validation keyword "items" in its own schema. The outer "items" is a property name, the inner one is a schema keyword. </p>
1252+
<p id="rfc.section.9.5.p.4">Note that there is an object member called "items", which is an array and therefore uses the validation keyword "items" in its own schema. The outer "items" is a property name, the inner one is a schema keyword. </p>
12001253
<pre>
12011254
{
12021255
"$id": "https://schema.example.com/thing-collection",
@@ -1300,21 +1353,23 @@ <h1 id="rfc.section.9.5"><a href="#rfc.section.9.5">9.5.</a> Collections</h1>
13001353
}
13011354
}
13021355
</pre>
1303-
<p>Here are all of the links that apply to this instance, including those that are referenced by using the "thing" schema for the individual items. The "self" links for the overal resource and each individual item are distinguished by different context pointers. Note also that the "item" and "self" links for a given thing have identical target URIs but different context pointers. </p>
1356+
<p>Here are all of the links that apply to this instance, including those that are referenced by using the "thing" schema for the individual items. The "self" links for the overall resource and each individual item are distinguished by different context pointers. Note also that the "item" and "self" links for a given thing have identical target URIs but different context pointers. </p>
13041357
<pre>
13051358
[
13061359
{
13071360
"contextUri": "https://api.example.com/things",
13081361
"contextPointer": "",
13091362
"rel": "self",
1310-
"targetUri": "https://api.example.com/things?offset=20,limit=2",
1363+
"targetUri":
1364+
"https://api.example.com/things?offset=20,limit=2",
13111365
"attachmentPointer": ""
13121366
},
13131367
{
13141368
"contextUri": "https://api.example.com/things",
13151369
"contextPointer": "",
13161370
"rel": "next",
1317-
"targetUri": "https://api.example.com/things?offset=22,limit=2",
1371+
"targetUri":
1372+
"https://api.example.com/things?offset=22,limit=2",
13181373
"attachmentPointer": ""
13191374
},
13201375
{
@@ -1360,8 +1415,8 @@ <h1 id="rfc.section.9.5"><a href="#rfc.section.9.5">9.5.</a> Collections</h1>
13601415
}
13611416
</pre>
13621417
<p>Here we see the "submissionSchema" indicating that we can create a single "thing" by submitting a representation (minus server-created fields such as "id") to the collection that is this link's target schema. While we cannot, in general, make assumptions about the semantics of making a data submission request (in HTTP terms, a POST), <a href="#collectionAndItem">Section 6.2.3</a> tells us that we MAY make such an assumption when the link relation is "collection", and that hyper-schema authors MUST NOT use a "collection" link if the data submission operation has semantics other than item creation. </p>
1363-
<p><a id="CREF10" class="info">[CREF10]<span class="info">I left off the scrolling parameters for this link. Technically, the link should go to the page containing the specific "thing" that is the context of the link. If the collection is using semantic sorting, then this is do-able (ideally setting the page boundary such that this is the first item, and allowing input on the page count / "limit" parameter). But getting into semantic scrolling/pagination seems way too involved for this example. </span></a> </p>
1364-
<p><a id="CREF11" class="info">[CREF11]<span class="info">Note also that POST-ing to a collection page that will not contain the created item also seems weird. While retrieving the collection from a query parameter-less URI will still retrieve a page, that's a limit imposed by the server. POST-ing to such a URI and disregarding the "default" values for the parameters seems correct. This is another reason to *not* automatically write default values into the query. </span></a> </p>
1418+
<p><a id="CREF9" class="info">[CREF9]<span class="info">I left off the scrolling parameters for this link. Technically, the link should go to the page containing the specific "thing" that is the context of the link. If the collection is using semantic sorting, then this is do-able (ideally setting the page boundary such that this is the first item, and allowing input on the page count / "limit" parameter). But getting into semantic scrolling/pagination seems way too involved for this example. </span></a> </p>
1419+
<p><a id="CREF10" class="info">[CREF10]<span class="info">Note also that POST-ing to a collection page that will not contain the created item also seems weird. While retrieving the collection from a query parameter-less URI will still retrieve a page, that's a limit imposed by the server. POST-ing to such a URI and disregarding the "default" values for the parameters seems correct. This is another reason to *not* automatically write default values into the query. </span></a> </p>
13651420
<p id="rfc.section.9.5.p.8">But what if we do not have any "thing"s yet? We cannot get to the individual "thing" schema as there is no individual "thing" to fetch. And the "tag:rel.example.com,2017:thing" link in the entry point resource does not indicate how to create a "thing". The "self" link requires the "id" to already exist, but it is assigned by the server. So we need to add another link to our entry point schema: </p>
13661421
<p>This LDO would be added to the top-level "links" array in the entry point resource's hyper-schema. </p>
13671422
<pre>
@@ -1380,15 +1435,15 @@ <h1 id="rfc.section.9.5"><a href="#rfc.section.9.5">9.5.</a> Collections</h1>
13801435
}
13811436
</pre>
13821437
<p>Now we see the scrolling parameters being accepted as input, so we can jump to any scroll window within the collection. </p>
1383-
<p><a id="CREF12" class="info">[CREF12]<span class="info">Here we also see the "submissionSchema" to use to create a "thing", but how do we recognize it? We can't use a "collection" link relation here, because there is no identifiable "thing" to serve as the context resource. We could look at the submission schema, notice that it has a "collection" link and is therefore an item, and notice that its "collection" link produces the same(-ish?) URI, but that seems overly complicated and also gets into trouble with query parameters again. </span></a> </p>
1438+
<p><a id="CREF11" class="info">[CREF11]<span class="info">Here we also see the "submissionSchema" to use to create a "thing", but how do we recognize it? We can't use a "collection" link relation here, because there is no identifiable "thing" to serve as the context resource. We could look at the submission schema, notice that it has a "collection" link and is therefore an item, and notice that its "collection" link produces the same(-ish?) URI, but that seems overly complicated and also gets into trouble with query parameters again. </span></a> </p>
13841439
<h1 id="rfc.section.10"><a href="#rfc.section.10">10.</a> <a href="#security" id="security">Security Considerations</a></h1>
13851440
<p>
1386-
<a id="CREF13" class="info">[CREF13]<span class="info">Need to reference the core and validation security considerations.</span></a>
1441+
<a id="CREF12" class="info">[CREF12]<span class="info">Need to reference the core and validation security considerations.</span></a>
13871442
</p>
13881443
<h1 id="rfc.section.10.1"><a href="#rfc.section.10.1">10.1.</a> "self" links</h1>
13891444
<p id="rfc.section.10.1.p.1">When link relation of "self" is used to denote a full representation of an object, the user agent SHOULD NOT consider the representation to be the authoritative representation of the resource denoted by the target URI if the target URI is not equivalent to or a sub-path of the URI used to request the resource representation which contains the target URI with the "self" link. </p>
13901445
<h1 id="rfc.section.10.2"><a href="#rfc.section.10.2">10.2.</a> Target attributes</h1>
1391-
<p><a id="CREF14" class="info">[CREF14]<span class="info">This whole section needs more work, but I do like having security concerns around target interactions consolidated and addressed as a whole. </span></a> </p>
1446+
<p><a id="CREF13" class="info">[CREF13]<span class="info">This whole section needs more work, but I do like having security concerns around target interactions consolidated and addressed as a whole. </span></a> </p>
13921447
<p id="rfc.section.10.2.p.2">The "targetMediaType" property in link definitions defines the expected format of the link's target. However, this is advisory only, and MUST NOT be considered authoritative. </p>
13931448
<p id="rfc.section.10.2.p.3">When choosing how to interpret data, the type information provided by the server (or inferred from the filename, or any other usual method) MUST be the only consideration, and the "targetMediaType" property of the link MUST NOT be used. User agents MAY use this information to determine how they represent the link or where to display it (for example hover-text, opening in a new tab). If user agents decide to pass the link to an external program, they SHOULD first verify that the data is of a type that would normally be passed to that external program. </p>
13941449
<p id="rfc.section.10.2.p.4">This is to guard against re-interpretation of "safe" data, similar to the precautions for "targetSchema". </p>
@@ -1520,9 +1575,9 @@ <h1 id="rfc.appendix.A.2"><a href="#rfc.appendix.A.2">A.2.</a> Responses and err
15201575
<p id="rfc.section.A.2.p.1">Because a hyper-schema represents a single resource at a time, it does not provide for an enumeration of all possible responses to protocol operations performed with links. Each response, including errors, is considered its own (possibly anonymous) resource, and should identify its own hyper-schema, and optionally use an appropriate media type such as <a href="#RFC7807">RFC 7807's "application/problem+json"</a> <cite title="NONE">[RFC7807]</cite>, to allow the user agent or client application to interpret any information that is provided beyond the protocol's own status reporting. </p>
15211576
<h1 id="rfc.appendix.A.3"><a href="#rfc.appendix.A.3">A.3.</a> <a href="#staticAnalysis" id="staticAnalysis">Static analysis of an API's hyper-schemas</a></h1>
15221577
<p id="rfc.section.A.3.p.1">It is possible to statically analyze a set of hyper-schemas without instance data in order to generate output such as documentation or code. However, the full feature set of both validation and hyper-schema cannot be accessed without runtime instance data. </p>
1523-
<p id="rfc.section.A.3.p.2">This is an intentional design choice to provide the maximum runtime flexibility for hypermedia systems. JSON Schema as a media type allows for establishing additional vocabularies for static analysis and content generation, which are not addressed in this specification. Additionally, individual systems may restrict their usage to subsets that can be analyzed statically if full design-time description is a goal. <a id="CREF15" class="info">[CREF15]<span class="info">Vocabularies for API documentation and other purposes have been proposed, and contributions are welcome at https://github.com/json-schema-org/json-schema-vocabularies </span></a> </p>
1578+
<p id="rfc.section.A.3.p.2">This is an intentional design choice to provide the maximum runtime flexibility for hypermedia systems. JSON Schema as a media type allows for establishing additional vocabularies for static analysis and content generation, which are not addressed in this specification. Additionally, individual systems may restrict their usage to subsets that can be analyzed statically if full design-time description is a goal. <a id="CREF14" class="info">[CREF14]<span class="info">Vocabularies for API documentation and other purposes have been proposed, and contributions are welcome at https://github.com/json-schema-org/json-schema-vocabularies </span></a> </p>
15241579
<h1 id="rfc.appendix.B"><a href="#rfc.appendix.B">Appendix B.</a> Change Log</h1>
1525-
<p><a id="CREF16" class="info">[CREF16]<span class="info">This section to be removed before leaving Internet-Draft status.</span></a> </p>
1580+
<p><a id="CREF15" class="info">[CREF15]<span class="info">This section to be removed before leaving Internet-Draft status.</span></a> </p>
15261581
<p/>
15271582

15281583
<dl>

0 commit comments

Comments
 (0)