Skip to content

Commit 150d3ff

Browse files
committed
Split collection example
Do a basic collection/item example, and then add pagination as yet another example.
1 parent 6d4a1b7 commit 150d3ff

File tree

1 file changed

+186
-112
lines changed

1 file changed

+186
-112
lines changed

jsonschema-hyperschema.xml

Lines changed: 186 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1913,10 +1913,9 @@ Link: <https://api.example.com/trees/1/nodes/456> rev=up
19131913
<figure>
19141914
<preamble>
19151915
This schema describes a collection where each item representation is
1916-
identical to the individual resource item representation, and there
1917-
is enough metadata included in the collection representation to
1918-
produce pagination links. The "first" and "last" pagination links
1919-
were omitted as this is already a long example.
1916+
identical to the individual resource item representation. The actual
1917+
collection elements appear as an array within an object, as we will
1918+
add more fields to the object in the next example.
19201919
</preamble>
19211920
<artwork>
19221921
<![CDATA[{
@@ -1940,13 +1939,173 @@ Link: <https://api.example.com/trees/1/nodes/456> rev=up
19401939
}
19411940
]
19421941
}
1942+
}
1943+
},
1944+
"links": [
1945+
{
1946+
"rel": "self",
1947+
"href": "things",
1948+
"targetSchema": {"$ref": "#"}
1949+
}
1950+
]
1951+
}]]>
1952+
</artwork>
1953+
</figure>
1954+
<figure>
1955+
<artwork>
1956+
<![CDATA[{
1957+
"elements": [
1958+
{"id": 12345, "data": {}},
1959+
{"id": 67890, "data": {}}
1960+
]
1961+
}]]>
1962+
</artwork>
1963+
</figure>
1964+
<figure>
1965+
<preamble>
1966+
Here are all of the links that apply to this instance,
1967+
including those that are referenced by using the "thing"
1968+
schema for the individual items. The "self" links for
1969+
the overall resource and each individual item are
1970+
distinguished by different context pointers. Note also
1971+
that the "item" and "self" links for a given thing have
1972+
identical target URIs but different context pointers.
1973+
</preamble>
1974+
<artwork>
1975+
<![CDATA[[
1976+
{
1977+
"contextUri": "https://api.example.com/things",
1978+
"contextPointer": "",
1979+
"rel": "self",
1980+
"targetUri": "https://api.example.com/things",
1981+
"attachmentPointer": ""
1982+
},
1983+
{
1984+
"contextUri": "https://api.example.com/things",
1985+
"contextPointer": "",
1986+
"rel": "item",
1987+
"targetUri": "https://api.example.com/things/1234",
1988+
"attachmentPointer": "/elements/0"
1989+
},
1990+
{
1991+
"contextUri": "https://api.example.com/things",
1992+
"contextPointer": "",
1993+
"rel": "item",
1994+
"targetUri": "https://api.example.com/things/67890",
1995+
"attachmentPointer": "/elements/1"
1996+
},
1997+
{
1998+
"contextUri": "https://api.example.com/things",
1999+
"contextPointer": "/elements/0",
2000+
"rel": "self",
2001+
"targetUri": "https://api.example.com/things/1234",
2002+
"attachmentPointer": "/elements/0"
2003+
},
2004+
{
2005+
"contextUri": "https://api.example.com/things",
2006+
"contextPointer": "/elements/1",
2007+
"rel": "self",
2008+
"targetUri": "https://api.example.com/things/67890",
2009+
"attachmentPointer": "/elements/1"
2010+
}
2011+
]]]>
2012+
2013+
</artwork>
2014+
</figure>
2015+
<t>
2016+
To fully specify our collection, we also need to add the following
2017+
link to our "thing" schema. Note that this would cause it to also
2018+
appear as a link in each item in the collection representation, which
2019+
is a good example of why it is best to only construct links upon request.
2020+
There is no need for having as many functionally identical "collection"
2021+
links as there are items in a collection page on every collection
2022+
representation.
2023+
</t>
2024+
<figure>
2025+
<preamble>
2026+
This link would be added to the top-level "links" array in the
2027+
"https://schemasexample.com/thing" schema.
2028+
</preamble>
2029+
<artwork>
2030+
<![CDATA[{
2031+
"rel": "collection",
2032+
"href": "/things",
2033+
"targetSchema": {"$ref": "thing-collection#"},
2034+
"submissionSchema": {"$ref": "#"}
2035+
}]]>
2036+
</artwork>
2037+
<postamble>
2038+
Here we see the "submissionSchema" indicating that we can create
2039+
a single "thing" by submitting a representation (minus server-created
2040+
fields such as "id") to the collection that is this link's target
2041+
schema. While we cannot, in general, make assumptions about the
2042+
semantics of making a data submission request (in HTTP terms, a POST),
2043+
<xref target="collectionAndItem" /> tells us that we MAY make such
2044+
an assumption when the link relation is "collection", and that
2045+
hyper-schema authors MUST NOT use a "collection" link if the data
2046+
submission operation has semantics other than item creation.
2047+
</postamble>
2048+
</figure>
2049+
<t>
2050+
But what if we do not have any "thing"s yet? We cannot get to the
2051+
individual "thing" schema as there is no individual "thing" to fetch.
2052+
And the "tag:rel.example.com,2017:thing" link in the entry point
2053+
resource does not indicate how to create a "thing". The "self" link
2054+
requires the "id" to already exist, but it is assigned by the server.
2055+
So we need to add another link to our entry point schema:
2056+
</t>
2057+
<figure>
2058+
<preamble>
2059+
This LDO would be added to the top-level "links" array in the entry
2060+
point resource's hyper-schema.
2061+
</preamble>
2062+
<artwork>
2063+
<![CDATA[{
2064+
"rel": "tag:rel.example.com,2017:thing-collection",
2065+
"href": "/things",
2066+
"submissionSchema": {
2067+
"$ref": "thing#"
2068+
},
2069+
"targetSchema": {
2070+
"$ref": "thing-collection#"
2071+
}
2072+
}]]>
2073+
</artwork>
2074+
</figure>
2075+
<t>
2076+
<cref>
2077+
Here we also see the "submissionSchema" to use to create a "thing",
2078+
but how do we recognize it? We can't use a "collection" link relation
2079+
here, because there is no identifiable "thing" to serve as the context
2080+
resource. We could look at the submission schema, notice that it
2081+
has a "collection" link and is therefore an item, and notice that
2082+
its "collection" link produces the same(-ish?) URI, but that seems
2083+
overly complicated. And gets more so once pagination and filtering
2084+
are introduced.
2085+
</cref>
2086+
</t>
2087+
</section>
2088+
<section title="Pagination">
2089+
<figure>
2090+
<preamble>
2091+
Here we add pagination to our collection. There is a "meta" section
2092+
to hold the information about current, next, and previous pages.
2093+
Most of the schema is the same as in the previous section and has been
2094+
omitted. Only new fields and new or (in the case of the main "self" link)
2095+
changed links are shown in full.
2096+
</preamble>
2097+
<artwork>
2098+
<![CDATA[{
2099+
"properties": {
2100+
"elements": {
2101+
...
19432102
},
19442103
"meta": {
19452104
"type": "object",
19462105
"properties": {
1947-
"prev": {"$ref": "#/definitions/scrolling"},
1948-
"current": {"$ref": "#/definitions/scrolling"},
1949-
"next": {"$ref": "#/definitions/scrolling"}
2106+
"prev": {"$ref": "#/definitions/pagination"},
2107+
"current": {"$ref": "#/definitions/pagination"},
2108+
"next": {"$ref": "#/definitions/pagination"}
19502109
}
19512110
}
19522111
},
@@ -1983,7 +2142,7 @@ Link: <https://api.example.com/trees/1/nodes/456> rev=up
19832142
}
19842143
],
19852144
"definitions": {
1986-
"scrolling": {
2145+
"pagination": {
19872146
"type": "object",
19882147
"properties": {
19892148
"offset": {
@@ -2006,12 +2165,13 @@ Link: <https://api.example.com/trees/1/nodes/456> rev=up
20062165
Notice that the "self" link includes the pagination query
20072166
that produced the exact representation, rather than being
20082167
a generic link to the collection allowing selecting the
2009-
page via input. There is no link for manual page selection
2010-
in the example as shown here, nor is there a "submissionSchema"
2011-
for item creation, but we will consider those additions further down.
2168+
page via input.
20122169
</postamble>
20132170
</figure>
20142171
<figure>
2172+
<preamble>
2173+
Given this instance:
2174+
</preamble>
20152175
<artwork>
20162176
<![CDATA[{
20172177
"elements": [
@@ -2033,13 +2193,9 @@ Link: <https://api.example.com/trees/1/nodes/456> rev=up
20332193
</figure>
20342194
<figure>
20352195
<preamble>
2036-
Here are all of the links that apply to this instance,
2037-
including those that are referenced by using the "thing"
2038-
schema for the individual items. The "self" links for
2039-
the overall resource and each individual item are
2040-
distinguished by different context pointers. Note also
2041-
that the "item" and "self" links for a given thing have
2042-
identical target URIs but different context pointers.
2196+
Here are all of the links that apply to this instance
2197+
that either did not appear in the previous example or
2198+
have been changed with pagination added.
20432199
</preamble>
20442200
<artwork>
20452201
<![CDATA[[
@@ -2058,34 +2214,6 @@ Link: <https://api.example.com/trees/1/nodes/456> rev=up
20582214
"targetUri":
20592215
"https://api.example.com/things?offset=22,limit=2",
20602216
"attachmentPointer": ""
2061-
},
2062-
{
2063-
"contextUri": "https://api.example.com/things",
2064-
"contextPointer": "",
2065-
"rel": "item",
2066-
"targetUri": "https://api.example.com/things/1234",
2067-
"attachmentPointer": "/elements/0"
2068-
},
2069-
{
2070-
"contextUri": "https://api.example.com/things",
2071-
"contextPointer": "",
2072-
"rel": "item",
2073-
"targetUri": "https://api.example.com/things/67890",
2074-
"attachmentPointer": "/elements/1"
2075-
},
2076-
{
2077-
"contextUri": "https://api.example.com/things",
2078-
"contextPointer": "/elements/0",
2079-
"rel": "self",
2080-
"targetUri": "https://api.example.com/things/1234",
2081-
"attachmentPointer": "/elements/0"
2082-
},
2083-
{
2084-
"contextUri": "https://api.example.com/things",
2085-
"contextPointer": "/elements/1",
2086-
"rel": "self",
2087-
"targetUri": "https://api.example.com/things/67890",
2088-
"attachmentPointer": "/elements/1"
20892217
}
20902218
]]]>
20912219

@@ -2097,49 +2225,15 @@ Link: <https://api.example.com/trees/1/nodes/456> rev=up
20972225
that the link is not usable with this particular instance.
20982226
</postamble>
20992227
</figure>
2100-
<t>
2101-
To fully specify our collection, we also need to add the following
2102-
link to our "thing" schema. Note that this would cause it to also
2103-
appear as a link in each item in the collection representation, which
2104-
is a good example of why it is best to only construct links upon request.
2105-
There is no need for having as many functionally identical "collection"
2106-
links as there are items in a collection page on every collection
2107-
representation.
2108-
</t>
2109-
<figure>
2110-
<preamble>
2111-
This link would be added to the top-level "links" array in the
2112-
"https://schema.example.com/thing" schema.
2113-
</preamble>
2114-
<artwork>
2115-
<![CDATA[{
2116-
"rel": "collection",
2117-
"href": "/things",
2118-
"targetSchema": {"$ref": "thing-collection#"},
2119-
"submissionSchema": {"$ref": "#"}
2120-
}]]>
2121-
</artwork>
2122-
<postamble>
2123-
Here we see the "submissionSchema" indicating that we can create
2124-
a single "thing" by submitting a representation (minus server-created
2125-
fields such as "id") to the collection that is this link's target
2126-
schema. While we cannot, in general, make assumptions about the
2127-
semantics of making a data submission request (in HTTP terms, a POST),
2128-
<xref target="collectionAndItem" /> tells us that we MAY make such
2129-
an assumption when the link relation is "collection", and that
2130-
hyper-schema authors MUST NOT use a "collection" link if the data
2131-
submission operation has semantics other than item creation.
2132-
</postamble>
2133-
</figure>
21342228
<t>
21352229
<cref>
2136-
I left off the scrolling parameters for this link. Technically,
2137-
the link should go to the page containing the specific "thing"
2138-
that is the context of the link. If the collection is using
2139-
semantic sorting, then this is do-able (ideally setting
2140-
the page boundary such that this is the first item, and allowing
2141-
input on the page count / "limit" parameter). But getting into
2142-
semantic scrolling/pagination seems way too involved for this
2230+
It's not clear how pagination should work with the link from the
2231+
entry point resource or the "collection" link in the item.
2232+
Technically, link from an item to a paginated or filtered
2233+
collection should go to a page/filter that contains the link
2234+
context. If the collection is using semantic sorting instead
2235+
of a plain integer limit and offset, then this is possible.
2236+
But getting into semantic pagination seems way too involved for this
21432237
example.
21442238
</cref>
21452239
</t>
@@ -2154,24 +2248,16 @@ Link: <https://api.example.com/trees/1/nodes/456> rev=up
21542248
</cref>
21552249
</t>
21562250
<t>
2157-
But what if we do not have any "thing"s yet? We cannot get to the
2158-
individual "thing" schema as there is no individual "thing" to fetch.
2159-
And the "tag:rel.example.com,2017:thing" link in the entry point
2160-
resource does not indicate how to create a "thing". The "self" link
2161-
requires the "id" to already exist, but it is assigned by the server.
2162-
So we need to add another link to our entry point schema:
2251+
Let's also update our entry point link to include pagination, specifically
2252+
allowing arbitrary input to choose the page:
21632253
</t>
21642254
<figure>
2165-
<preamble>
2166-
This LDO would be added to the top-level "links" array in the entry
2167-
point resource's hyper-schema.
2168-
</preamble>
21692255
<artwork>
21702256
<![CDATA[{
21712257
"rel": "tag:rel.example.com,2017:thing-collection",
21722258
"href": "/things{?offset,limit}",
21732259
"hrefSchema": {
2174-
"$ref": "thing-collection#/definitions/scrolling"
2260+
"$ref": "thing-collection#/definitions/pagination"
21752261
},
21762262
"submissionSchema": {
21772263
"$ref": "thing#"
@@ -2182,22 +2268,10 @@ Link: <https://api.example.com/trees/1/nodes/456> rev=up
21822268
}]]>
21832269
</artwork>
21842270
<postamble>
2185-
Now we see the scrolling parameters being accepted as input, so
2186-
we can jump to any scroll window within the collection.
2271+
Now we see the pagination parameters being accepted as input, so
2272+
we can jump to any page within the collection.
21872273
</postamble>
21882274
</figure>
2189-
<t>
2190-
<cref>
2191-
Here we also see the "submissionSchema" to use to create a "thing",
2192-
but how do we recognize it? We can't use a "collection" link relation
2193-
here, because there is no identifiable "thing" to serve as the context
2194-
resource. We could look at the submission schema, notice that it
2195-
has a "collection" link and is therefore an item, and notice that
2196-
its "collection" link produces the same(-ish?) URI, but that seems
2197-
overly complicated and also gets into trouble with query parameters
2198-
again.
2199-
</cref>
2200-
</t>
22012275
</section>
22022276
</section>
22032277

0 commit comments

Comments
 (0)