Skip to content

Commit 7d0daba

Browse files
authored
Merge pull request #678 from handrews/trailing-slash
Clarify trailing slash ref-resolution weirdness
2 parents b6fd7a0 + 960069e commit 7d0daba

File tree

1 file changed

+59
-40
lines changed

1 file changed

+59
-40
lines changed

jsonschema-hyperschema.xml

Lines changed: 59 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@
176176
<postamble>
177177
If the instance is {"id": 1234}, and its base URI according to
178178
<xref target="RFC3986">RFC 3986 section 5.1</xref>, is
179-
"https://api.example.com/", then "https://api.example.com/thing/1234"
179+
"https://example.com/api/", then "https://example.com/api/thing/1234"
180180
is the resulting link's target URI.
181181
</postamble>
182182
</figure>
@@ -1551,14 +1551,14 @@ for varname in templateData:
15511551
<section title="Entry Point Links, No Templates" anchor="entryPoint">
15521552
<t>
15531553
For this example, we will assume an example API with a documented
1554-
entry point URI of https://api.example.com, which is an empty JSON object
1554+
entry point URI of https://example.com/api, which is an empty JSON object
15551555
with a link to a schema. Here, the entry point has no data of its
15561556
own and exists only to provide an initial set of links:
15571557
</t>
15581558
<figure>
15591559
<artwork>
15601560
<![CDATA[
1561-
GET https://api.example.com HTTP/1.1
1561+
GET https://example.com/api HTTP/1.1
15621562
15631563
200 OK
15641564
Content-Type: application/json
@@ -1570,23 +1570,22 @@ Link: <https://schema.example.com/entry>; rel="describedBy"
15701570
<t>
15711571
The linked hyper-schema defines the API's base URI and provides
15721572
two links: an "about" link to API documentation, and a "self"
1573-
link indicating that this is a schema for the base URI. In this
1574-
case the base URI is also the entry point URI.
1573+
link indicating that this is a schema for the base URI.
15751574
</t>
15761575
<figure>
15771576
<artwork>
15781577
<![CDATA[
15791578
{
15801579
"$id": "https://schema.example.com/entry",
15811580
"$schema": "http://json-schema.org/draft-08/hyper-schema#",
1582-
"base": "https://api.example.com/",
1581+
"base": "https://example.com/api/",
15831582
"links": [
15841583
{
15851584
"rel": "self",
1586-
"href": ""
1585+
"href": "../api",
15871586
}, {
15881587
"rel": "about",
1589-
"href": "/docs"
1588+
"href": "docs"
15901589
}
15911590
]
15921591
}]]>
@@ -1596,21 +1595,41 @@ Link: <https://schema.example.com/entry>; rel="describedBy"
15961595
These are the simplest possible links, with only a relation type and
15971596
an "href" with no template variables. They resolve as follows:
15981597
</t>
1598+
<t>
1599+
The duplication of "api" in both the base and the "../api"
1600+
href in the "self" link is due to quirks of the RFC 3986
1601+
URI-reference resolution algorithm. In order for relative
1602+
URI-references to work well in general, the base URI needs
1603+
to include a trailing slash. The "about" link with its "docs"
1604+
href shows the common case of relative references, which is
1605+
used in the other examples in this document.
1606+
</t>
1607+
<t>
1608+
However, if an API uses URIs without trailing slashes for its resources,
1609+
there is no way to provide a relative reference that just removes a
1610+
trailing slash without duplicating the path component above it.
1611+
Which makes the case of the entry point resource, which differs
1612+
from the base URI only in terms of the trailing slash, somewhat awkward.
1613+
</t>
1614+
<t>
1615+
Resource URIs, of course, may have trailing slashes, but this example
1616+
is intended to highlight this frequently confusing special case.
1617+
</t>
15991618
<figure>
16001619
<artwork>
16011620
<![CDATA[[
16021621
{
1603-
"contextUri": "https://api.example.com",
1622+
"contextUri": "https://example.com/api",
16041623
"contextPointer": "",
16051624
"rel": "self",
1606-
"targetUri": "https://api.example.com",
1625+
"targetUri": "https://example.com/api",
16071626
"attachmentPointer": ""
16081627
},
16091628
{
1610-
"contextUri": "https://api.example.com",
1629+
"contextUri": "https://example.com/api",
16111630
"contextPointer": "",
16121631
"rel": "about",
1613-
"targetUri": "https://api.example.com/docs",
1632+
"targetUri": "https://example.com/api/docs",
16141633
"attachmentPointer": ""
16151634
}
16161635
]]]>
@@ -1633,7 +1652,7 @@ Link: <https://schema.example.com/entry>; rel="describedBy"
16331652
<![CDATA[{
16341653
"$id": "https://schema.example.com/thing",
16351654
"$schema": "http://json-schema.org/draft-08/hyper-schema#",
1636-
"base": "https://api.example.com/",
1655+
"base": "https://example.com/api/",
16371656
"type": "object",
16381657
"required": ["data"],
16391658
"properties": {
@@ -1830,7 +1849,7 @@ Link: <https://schema.example.com/entry>; rel="describedBy"
18301849
</list>
18311850
</t>
18321851
<t>
1833-
So, given the following instance retrieved from "https://api.example.com/stuff":
1852+
So, given the following instance retrieved from "https://example.com/api/stuff":
18341853
</t>
18351854
<figure>
18361855
<artwork>
@@ -1848,7 +1867,7 @@ Link: <https://schema.example.com/entry>; rel="describedBy"
18481867
<figure>
18491868
<artwork>
18501869
<![CDATA[{
1851-
"contextUri": "https://api.example.com/stuff",
1870+
"contextUri": "https://example.com/api/stuff",
18521871
"contextPointer": "",
18531872
"rel": "author",
18541873
"hrefInputTemplates": [
@@ -1902,14 +1921,14 @@ Link: <https://schema.example.com/entry>; rel="describedBy"
19021921
</preamble>
19031922
<artwork>
19041923
<![CDATA[
1905-
GET https://api.example.com/trees/1/nodes/123 HTTP/1.1
1924+
GET https://example.com/api/trees/1/nodes/123 HTTP/1.1
19061925
19071926
200 OK
19081927
Content-Type: application/json
1909-
Link: <https://api.example.com/trees/1/nodes/123>; rel="self"
1910-
Link: <https://api.example.com/trees/1/nodes/123>; rel="up";
1911-
anchor="https://api.example.com/trees/1/nodes/456"
1912-
Link: <https://api.example.com/trees/1/nodes/456>; rev="up"
1928+
Link: <https://example.com/api/trees/1/nodes/123>; rel="self"
1929+
Link: <https://example.com/api/trees/1/nodes/123>; rel="up";
1930+
anchor="https://example.com/api/trees/1/nodes/456"
1931+
Link: <https://example.com/api/trees/1/nodes/456>; rev="up"
19131932
{
19141933
"id": 123,
19151934
"treeId": 1,
@@ -1998,7 +2017,7 @@ Link: <https://api.example.com/trees/1/nodes/456>; rev="up"
19982017
<![CDATA[{
19992018
"$id": "https://schema.example.com/thing",
20002019
"$schema": "http://json-schema.org/draft-08/hyper-schema#",
2001-
"base": "https://api.example.com/",
2020+
"base": "https://example.com/api/",
20022021
"type": "object",
20032022
"required": ["data"],
20042023
"properties": {
@@ -2051,7 +2070,7 @@ Link: <https://api.example.com/trees/1/nodes/456>; rev="up"
20512070
<![CDATA[{
20522071
"$id": "https://schema.example.com/thing-collection",
20532072
"$schema": "http://json-schema.org/draft-08/hyper-schema#",
2054-
"base": "https://api.example.com/",
2073+
"base": "https://example.com/api/",
20552074
"type": "object",
20562075
"required": ["elements"],
20572076
"properties": {
@@ -2104,52 +2123,52 @@ Link: <https://api.example.com/trees/1/nodes/456>; rev="up"
21042123
<artwork>
21052124
<![CDATA[[
21062125
{
2107-
"contextUri": "https://api.example.com/things",
2126+
"contextUri": "https://example.com/api/things",
21082127
"contextPointer": "",
21092128
"rel": "self",
2110-
"targetUri": "https://api.example.com/things",
2129+
"targetUri": "https://example.com/api/things",
21112130
"attachmentPointer": ""
21122131
},
21132132
{
2114-
"contextUri": "https://api.example.com/things",
2133+
"contextUri": "https://example.com/api/things",
21152134
"contextPointer": "/elements/0",
21162135
"rel": "self",
2117-
"targetUri": "https://api.example.com/things/12345",
2136+
"targetUri": "https://example.com/api/things/12345",
21182137
"attachmentPointer": "/elements/0"
21192138
},
21202139
{
2121-
"contextUri": "https://api.example.com/things",
2140+
"contextUri": "https://example.com/api/things",
21222141
"contextPointer": "/elements/1",
21232142
"rel": "self",
2124-
"targetUri": "https://api.example.com/things/67890",
2143+
"targetUri": "https://example.com/api/things/67890",
21252144
"attachmentPointer": "/elements/1"
21262145
},
21272146
{
2128-
"contextUri": "https://api.example.com/things",
2147+
"contextUri": "https://example.com/api/things",
21292148
"contextPointer": "",
21302149
"rel": "item",
2131-
"targetUri": "https://api.example.com/things/12345",
2150+
"targetUri": "https://example.com/api/things/12345",
21322151
"attachmentPointer": "/elements/0"
21332152
},
21342153
{
2135-
"contextUri": "https://api.example.com/things",
2154+
"contextUri": "https://example.com/api/things",
21362155
"contextPointer": "",
21372156
"rel": "item",
2138-
"targetUri": "https://api.example.com/things/67890",
2157+
"targetUri": "https://example.com/api/things/67890",
21392158
"attachmentPointer": "/elements/1"
21402159
},
21412160
{
2142-
"contextUri": "https://api.example.com/things",
2161+
"contextUri": "https://example.com/api/things",
21432162
"contextPointer": "/elements/0",
21442163
"rel": "collection",
2145-
"targetUri": "https://api.example.com/things",
2164+
"targetUri": "https://example.com/api/things",
21462165
"attachmentPointer": "/elements/0"
21472166
},
21482167
{
2149-
"contextUri": "https://api.example.com/things",
2168+
"contextUri": "https://example.com/api/things",
21502169
"contextPointer": "/elements/1",
21512170
"rel": "collection",
2152-
"targetUri": "https://api.example.com/things",
2171+
"targetUri": "https://example.com/api/things",
21532172
"attachmentPointer": "/elements/1"
21542173
}
21552174
]]]>
@@ -2310,19 +2329,19 @@ Link: <https://api.example.com/trees/1/nodes/456>; rev="up"
23102329
<artwork>
23112330
<![CDATA[[
23122331
{
2313-
"contextUri": "https://api.example.com/things",
2332+
"contextUri": "https://example.com/api/things",
23142333
"contextPointer": "",
23152334
"rel": "self",
23162335
"targetUri":
2317-
"https://api.example.com/things?offset=0&limit=2",
2336+
"https://example.com/api/things?offset=0&limit=2",
23182337
"attachmentPointer": ""
23192338
},
23202339
{
2321-
"contextUri": "https://api.example.com/things",
2340+
"contextUri": "https://example.com/api/things",
23222341
"contextPointer": "",
23232342
"rel": "next",
23242343
"targetUri":
2325-
"https://api.example.com/things?offset=3&limit=2",
2344+
"https://example.com/api/things?offset=3&limit=2",
23262345
"attachmentPointer": ""
23272346
}
23282347
]]]>

0 commit comments

Comments
 (0)