Skip to content

Commit d7a943b

Browse files
committed
Clarify trailing slash ref-resolution weirdness
There is no way to do RFC 3986 reference resolution that just removes a trailing slash without duplicating things. Every option is confusing and weird, but avoiding trailing slashes is increasingly common. Let's just face that and explain that it's weird and this is the best that can be done.
1 parent b6fd7a0 commit d7a943b

File tree

1 file changed

+46
-40
lines changed

1 file changed

+46
-40
lines changed

jsonschema-hyperschema.xml

Lines changed: 46 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,27 +1570,33 @@ 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
}]]>
15931592
</artwork>
1593+
<postamble>
1594+
Due to quirks of the RFC 3986 URI-reference resolution algorithm,
1595+
the "self" link needs to duplicate the "api" part of the path
1596+
in order to produce a URI without a trailing slash.
1597+
URIs, of course, may have trailing slashes, but this example
1598+
is intended to highlight this frequently confusing special case.
1599+
</postamble>
15941600
</figure>
15951601
<t>
15961602
These are the simplest possible links, with only a relation type and
@@ -1600,17 +1606,17 @@ Link: <https://schema.example.com/entry>; rel="describedBy"
16001606
<artwork>
16011607
<![CDATA[[
16021608
{
1603-
"contextUri": "https://api.example.com",
1609+
"contextUri": "https://example.com/api",
16041610
"contextPointer": "",
16051611
"rel": "self",
1606-
"targetUri": "https://api.example.com",
1612+
"targetUri": "https://example.com/api",
16071613
"attachmentPointer": ""
16081614
},
16091615
{
1610-
"contextUri": "https://api.example.com",
1616+
"contextUri": "https://example.com/api",
16111617
"contextPointer": "",
16121618
"rel": "about",
1613-
"targetUri": "https://api.example.com/docs",
1619+
"targetUri": "https://example.com/api/docs",
16141620
"attachmentPointer": ""
16151621
}
16161622
]]]>
@@ -1633,7 +1639,7 @@ Link: <https://schema.example.com/entry>; rel="describedBy"
16331639
<![CDATA[{
16341640
"$id": "https://schema.example.com/thing",
16351641
"$schema": "http://json-schema.org/draft-08/hyper-schema#",
1636-
"base": "https://api.example.com/",
1642+
"base": "https://example.com/api/",
16371643
"type": "object",
16381644
"required": ["data"],
16391645
"properties": {
@@ -1830,7 +1836,7 @@ Link: <https://schema.example.com/entry>; rel="describedBy"
18301836
</list>
18311837
</t>
18321838
<t>
1833-
So, given the following instance retrieved from "https://api.example.com/stuff":
1839+
So, given the following instance retrieved from "https://example.com/api/stuff":
18341840
</t>
18351841
<figure>
18361842
<artwork>
@@ -1848,7 +1854,7 @@ Link: <https://schema.example.com/entry>; rel="describedBy"
18481854
<figure>
18491855
<artwork>
18501856
<![CDATA[{
1851-
"contextUri": "https://api.example.com/stuff",
1857+
"contextUri": "https://example.com/api/stuff",
18521858
"contextPointer": "",
18531859
"rel": "author",
18541860
"hrefInputTemplates": [
@@ -1902,14 +1908,14 @@ Link: <https://schema.example.com/entry>; rel="describedBy"
19021908
</preamble>
19031909
<artwork>
19041910
<![CDATA[
1905-
GET https://api.example.com/trees/1/nodes/123 HTTP/1.1
1911+
GET https://example.com/api/trees/1/nodes/123 HTTP/1.1
19061912
19071913
200 OK
19081914
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"
1915+
Link: <https://example.com/api/trees/1/nodes/123>; rel="self"
1916+
Link: <https://example.com/api/trees/1/nodes/123>; rel="up";
1917+
anchor="https://example.com/api/trees/1/nodes/456"
1918+
Link: <https://example.com/api/trees/1/nodes/456>; rev="up"
19131919
{
19141920
"id": 123,
19151921
"treeId": 1,
@@ -1998,7 +2004,7 @@ Link: <https://api.example.com/trees/1/nodes/456>; rev="up"
19982004
<![CDATA[{
19992005
"$id": "https://schema.example.com/thing",
20002006
"$schema": "http://json-schema.org/draft-08/hyper-schema#",
2001-
"base": "https://api.example.com/",
2007+
"base": "https://example.com/api/",
20022008
"type": "object",
20032009
"required": ["data"],
20042010
"properties": {
@@ -2051,7 +2057,7 @@ Link: <https://api.example.com/trees/1/nodes/456>; rev="up"
20512057
<![CDATA[{
20522058
"$id": "https://schema.example.com/thing-collection",
20532059
"$schema": "http://json-schema.org/draft-08/hyper-schema#",
2054-
"base": "https://api.example.com/",
2060+
"base": "https://example.com/api/",
20552061
"type": "object",
20562062
"required": ["elements"],
20572063
"properties": {
@@ -2104,52 +2110,52 @@ Link: <https://api.example.com/trees/1/nodes/456>; rev="up"
21042110
<artwork>
21052111
<![CDATA[[
21062112
{
2107-
"contextUri": "https://api.example.com/things",
2113+
"contextUri": "https://example.com/api/things",
21082114
"contextPointer": "",
21092115
"rel": "self",
2110-
"targetUri": "https://api.example.com/things",
2116+
"targetUri": "https://example.com/api/things",
21112117
"attachmentPointer": ""
21122118
},
21132119
{
2114-
"contextUri": "https://api.example.com/things",
2120+
"contextUri": "https://example.com/api/things",
21152121
"contextPointer": "/elements/0",
21162122
"rel": "self",
2117-
"targetUri": "https://api.example.com/things/12345",
2123+
"targetUri": "https://example.com/api/things/12345",
21182124
"attachmentPointer": "/elements/0"
21192125
},
21202126
{
2121-
"contextUri": "https://api.example.com/things",
2127+
"contextUri": "https://example.com/api/things",
21222128
"contextPointer": "/elements/1",
21232129
"rel": "self",
2124-
"targetUri": "https://api.example.com/things/67890",
2130+
"targetUri": "https://example.com/api/things/67890",
21252131
"attachmentPointer": "/elements/1"
21262132
},
21272133
{
2128-
"contextUri": "https://api.example.com/things",
2134+
"contextUri": "https://example.com/api/things",
21292135
"contextPointer": "",
21302136
"rel": "item",
2131-
"targetUri": "https://api.example.com/things/12345",
2137+
"targetUri": "https://example.com/api/things/12345",
21322138
"attachmentPointer": "/elements/0"
21332139
},
21342140
{
2135-
"contextUri": "https://api.example.com/things",
2141+
"contextUri": "https://example.com/api/things",
21362142
"contextPointer": "",
21372143
"rel": "item",
2138-
"targetUri": "https://api.example.com/things/67890",
2144+
"targetUri": "https://example.com/api/things/67890",
21392145
"attachmentPointer": "/elements/1"
21402146
},
21412147
{
2142-
"contextUri": "https://api.example.com/things",
2148+
"contextUri": "https://example.com/api/things",
21432149
"contextPointer": "/elements/0",
21442150
"rel": "collection",
2145-
"targetUri": "https://api.example.com/things",
2151+
"targetUri": "https://example.com/api/things",
21462152
"attachmentPointer": "/elements/0"
21472153
},
21482154
{
2149-
"contextUri": "https://api.example.com/things",
2155+
"contextUri": "https://example.com/api/things",
21502156
"contextPointer": "/elements/1",
21512157
"rel": "collection",
2152-
"targetUri": "https://api.example.com/things",
2158+
"targetUri": "https://example.com/api/things",
21532159
"attachmentPointer": "/elements/1"
21542160
}
21552161
]]]>
@@ -2310,19 +2316,19 @@ Link: <https://api.example.com/trees/1/nodes/456>; rev="up"
23102316
<artwork>
23112317
<![CDATA[[
23122318
{
2313-
"contextUri": "https://api.example.com/things",
2319+
"contextUri": "https://example.com/api/things",
23142320
"contextPointer": "",
23152321
"rel": "self",
23162322
"targetUri":
2317-
"https://api.example.com/things?offset=0&limit=2",
2323+
"https://example.com/api/things?offset=0&limit=2",
23182324
"attachmentPointer": ""
23192325
},
23202326
{
2321-
"contextUri": "https://api.example.com/things",
2327+
"contextUri": "https://example.com/api/things",
23222328
"contextPointer": "",
23232329
"rel": "next",
23242330
"targetUri":
2325-
"https://api.example.com/things?offset=3&limit=2",
2331+
"https://example.com/api/things?offset=3&limit=2",
23262332
"attachmentPointer": ""
23272333
}
23282334
]]]>

0 commit comments

Comments
 (0)