Skip to content

Commit c6b4a59

Browse files
committed
Split collection example
Do a basic collection/item example, and then add pagination as yet another example.
1 parent 33bb0ba commit c6b4a59

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
@@ -1919,10 +1919,9 @@ Link: <https://api.example.com/trees/1/nodes/456> rev=up
19191919
<figure>
19201920
<preamble>
19211921
This schema describes a collection where each item representation is
1922-
identical to the individual resource item representation, and there
1923-
is enough metadata included in the collection representation to
1924-
produce pagination links. The "first" and "last" pagination links
1925-
were omitted as this is already a long example.
1922+
identical to the individual resource item representation. The actual
1923+
collection elements appear as an array within an object, as we will
1924+
add more fields to the object in the next example.
19261925
</preamble>
19271926
<artwork>
19281927
<![CDATA[{
@@ -1946,13 +1945,173 @@ Link: <https://api.example.com/trees/1/nodes/456> rev=up
19461945
}
19471946
]
19481947
}
1948+
}
1949+
},
1950+
"links": [
1951+
{
1952+
"rel": "self",
1953+
"href": "things",
1954+
"targetSchema": {"$ref": "#"}
1955+
}
1956+
]
1957+
}]]>
1958+
</artwork>
1959+
</figure>
1960+
<figure>
1961+
<artwork>
1962+
<![CDATA[{
1963+
"elements": [
1964+
{"id": 12345, "data": {}},
1965+
{"id": 67890, "data": {}}
1966+
]
1967+
}]]>
1968+
</artwork>
1969+
</figure>
1970+
<figure>
1971+
<preamble>
1972+
Here are all of the links that apply to this instance,
1973+
including those that are referenced by using the "thing"
1974+
schema for the individual items. The "self" links for
1975+
the overall resource and each individual item are
1976+
distinguished by different context pointers. Note also
1977+
that the "item" and "self" links for a given thing have
1978+
identical target URIs but different context pointers.
1979+
</preamble>
1980+
<artwork>
1981+
<![CDATA[[
1982+
{
1983+
"contextUri": "https://api.example.com/things",
1984+
"contextPointer": "",
1985+
"rel": "self",
1986+
"targetUri": "https://api.example.com/things",
1987+
"attachmentPointer": ""
1988+
},
1989+
{
1990+
"contextUri": "https://api.example.com/things",
1991+
"contextPointer": "",
1992+
"rel": "item",
1993+
"targetUri": "https://api.example.com/things/1234",
1994+
"attachmentPointer": "/elements/0"
1995+
},
1996+
{
1997+
"contextUri": "https://api.example.com/things",
1998+
"contextPointer": "",
1999+
"rel": "item",
2000+
"targetUri": "https://api.example.com/things/67890",
2001+
"attachmentPointer": "/elements/1"
2002+
},
2003+
{
2004+
"contextUri": "https://api.example.com/things",
2005+
"contextPointer": "/elements/0",
2006+
"rel": "self",
2007+
"targetUri": "https://api.example.com/things/1234",
2008+
"attachmentPointer": "/elements/0"
2009+
},
2010+
{
2011+
"contextUri": "https://api.example.com/things",
2012+
"contextPointer": "/elements/1",
2013+
"rel": "self",
2014+
"targetUri": "https://api.example.com/things/67890",
2015+
"attachmentPointer": "/elements/1"
2016+
}
2017+
]]]>
2018+
2019+
</artwork>
2020+
</figure>
2021+
<t>
2022+
To fully specify our collection, we also need to add the following
2023+
link to our "thing" schema. Note that this would cause it to also
2024+
appear as a link in each item in the collection representation, which
2025+
is a good example of why it is best to only construct links upon request.
2026+
There is no need for having as many functionally identical "collection"
2027+
links as there are items in a collection page on every collection
2028+
representation.
2029+
</t>
2030+
<figure>
2031+
<preamble>
2032+
This link would be added to the top-level "links" array in the
2033+
"https://schemasexample.com/thing" schema.
2034+
</preamble>
2035+
<artwork>
2036+
<![CDATA[{
2037+
"rel": "collection",
2038+
"href": "/things",
2039+
"targetSchema": {"$ref": "thing-collection#"},
2040+
"submissionSchema": {"$ref": "#"}
2041+
}]]>
2042+
</artwork>
2043+
<postamble>
2044+
Here we see the "submissionSchema" indicating that we can create
2045+
a single "thing" by submitting a representation (minus server-created
2046+
fields such as "id") to the collection that is this link's target
2047+
schema. While we cannot, in general, make assumptions about the
2048+
semantics of making a data submission request (in HTTP terms, a POST),
2049+
<xref target="collectionAndItem" /> tells us that we MAY make such
2050+
an assumption when the link relation is "collection", and that
2051+
hyper-schema authors MUST NOT use a "collection" link if the data
2052+
submission operation has semantics other than item creation.
2053+
</postamble>
2054+
</figure>
2055+
<t>
2056+
But what if we do not have any "thing"s yet? We cannot get to the
2057+
individual "thing" schema as there is no individual "thing" to fetch.
2058+
And the "tag:rel.example.com,2017:thing" link in the entry point
2059+
resource does not indicate how to create a "thing". The "self" link
2060+
requires the "id" to already exist, but it is assigned by the server.
2061+
So we need to add another link to our entry point schema:
2062+
</t>
2063+
<figure>
2064+
<preamble>
2065+
This LDO would be added to the top-level "links" array in the entry
2066+
point resource's hyper-schema.
2067+
</preamble>
2068+
<artwork>
2069+
<![CDATA[{
2070+
"rel": "tag:rel.example.com,2017:thing-collection",
2071+
"href": "/things",
2072+
"submissionSchema": {
2073+
"$ref": "thing#"
2074+
},
2075+
"targetSchema": {
2076+
"$ref": "thing-collection#"
2077+
}
2078+
}]]>
2079+
</artwork>
2080+
</figure>
2081+
<t>
2082+
<cref>
2083+
Here we also see the "submissionSchema" to use to create a "thing",
2084+
but how do we recognize it? We can't use a "collection" link relation
2085+
here, because there is no identifiable "thing" to serve as the context
2086+
resource. We could look at the submission schema, notice that it
2087+
has a "collection" link and is therefore an item, and notice that
2088+
its "collection" link produces the same(-ish?) URI, but that seems
2089+
overly complicated. And gets more so once pagination and filtering
2090+
are introduced.
2091+
</cref>
2092+
</t>
2093+
</section>
2094+
<section title="Pagination">
2095+
<figure>
2096+
<preamble>
2097+
Here we add pagination to our collection. There is a "meta" section
2098+
to hold the information about current, next, and previous pages.
2099+
Most of the schema is the same as in the previous section and has been
2100+
omitted. Only new fields and new or (in the case of the main "self" link)
2101+
changed links are shown in full.
2102+
</preamble>
2103+
<artwork>
2104+
<![CDATA[{
2105+
"properties": {
2106+
"elements": {
2107+
...
19492108
},
19502109
"meta": {
19512110
"type": "object",
19522111
"properties": {
1953-
"prev": {"$ref": "#/definitions/scrolling"},
1954-
"current": {"$ref": "#/definitions/scrolling"},
1955-
"next": {"$ref": "#/definitions/scrolling"}
2112+
"prev": {"$ref": "#/definitions/pagination"},
2113+
"current": {"$ref": "#/definitions/pagination"},
2114+
"next": {"$ref": "#/definitions/pagination"}
19562115
}
19572116
}
19582117
},
@@ -1989,7 +2148,7 @@ Link: <https://api.example.com/trees/1/nodes/456> rev=up
19892148
}
19902149
],
19912150
"definitions": {
1992-
"scrolling": {
2151+
"pagination": {
19932152
"type": "object",
19942153
"properties": {
19952154
"offset": {
@@ -2012,12 +2171,13 @@ Link: <https://api.example.com/trees/1/nodes/456> rev=up
20122171
Notice that the "self" link includes the pagination query
20132172
that produced the exact representation, rather than being
20142173
a generic link to the collection allowing selecting the
2015-
page via input. There is no link for manual page selection
2016-
in the example as shown here, nor is there a "submissionSchema"
2017-
for item creation, but we will consider those additions further down.
2174+
page via input.
20182175
</postamble>
20192176
</figure>
20202177
<figure>
2178+
<preamble>
2179+
Given this instance:
2180+
</preamble>
20212181
<artwork>
20222182
<![CDATA[{
20232183
"elements": [
@@ -2039,13 +2199,9 @@ Link: <https://api.example.com/trees/1/nodes/456> rev=up
20392199
</figure>
20402200
<figure>
20412201
<preamble>
2042-
Here are all of the links that apply to this instance,
2043-
including those that are referenced by using the "thing"
2044-
schema for the individual items. The "self" links for
2045-
the overall resource and each individual item are
2046-
distinguished by different context pointers. Note also
2047-
that the "item" and "self" links for a given thing have
2048-
identical target URIs but different context pointers.
2202+
Here are all of the links that apply to this instance
2203+
that either did not appear in the previous example or
2204+
have been changed with pagination added.
20492205
</preamble>
20502206
<artwork>
20512207
<![CDATA[[
@@ -2064,34 +2220,6 @@ Link: <https://api.example.com/trees/1/nodes/456> rev=up
20642220
"targetUri":
20652221
"https://api.example.com/things?offset=22,limit=2",
20662222
"attachmentPointer": ""
2067-
},
2068-
{
2069-
"contextUri": "https://api.example.com/things",
2070-
"contextPointer": "",
2071-
"rel": "item",
2072-
"targetUri": "https://api.example.com/things/1234",
2073-
"attachmentPointer": "/elements/0"
2074-
},
2075-
{
2076-
"contextUri": "https://api.example.com/things",
2077-
"contextPointer": "",
2078-
"rel": "item",
2079-
"targetUri": "https://api.example.com/things/67890",
2080-
"attachmentPointer": "/elements/1"
2081-
},
2082-
{
2083-
"contextUri": "https://api.example.com/things",
2084-
"contextPointer": "/elements/0",
2085-
"rel": "self",
2086-
"targetUri": "https://api.example.com/things/1234",
2087-
"attachmentPointer": "/elements/0"
2088-
},
2089-
{
2090-
"contextUri": "https://api.example.com/things",
2091-
"contextPointer": "/elements/1",
2092-
"rel": "self",
2093-
"targetUri": "https://api.example.com/things/67890",
2094-
"attachmentPointer": "/elements/1"
20952223
}
20962224
]]]>
20972225

@@ -2103,49 +2231,15 @@ Link: <https://api.example.com/trees/1/nodes/456> rev=up
21032231
that the link is not usable with this particular instance.
21042232
</postamble>
21052233
</figure>
2106-
<t>
2107-
To fully specify our collection, we also need to add the following
2108-
link to our "thing" schema. Note that this would cause it to also
2109-
appear as a link in each item in the collection representation, which
2110-
is a good example of why it is best to only construct links upon request.
2111-
There is no need for having as many functionally identical "collection"
2112-
links as there are items in a collection page on every collection
2113-
representation.
2114-
</t>
2115-
<figure>
2116-
<preamble>
2117-
This link would be added to the top-level "links" array in the
2118-
"https://schemasexample.com/thing" schema.
2119-
</preamble>
2120-
<artwork>
2121-
<![CDATA[{
2122-
"rel": "collection",
2123-
"href": "/things",
2124-
"targetSchema": {"$ref": "thing-collection#"},
2125-
"submissionSchema": {"$ref": "#"}
2126-
}]]>
2127-
</artwork>
2128-
<postamble>
2129-
Here we see the "submissionSchema" indicating that we can create
2130-
a single "thing" by submitting a representation (minus server-created
2131-
fields such as "id") to the collection that is this link's target
2132-
schema. While we cannot, in general, make assumptions about the
2133-
semantics of making a data submission request (in HTTP terms, a POST),
2134-
<xref target="collectionAndItem" /> tells us that we MAY make such
2135-
an assumption when the link relation is "collection", and that
2136-
hyper-schema authors MUST NOT use a "collection" link if the data
2137-
submission operation has semantics other than item creation.
2138-
</postamble>
2139-
</figure>
21402234
<t>
21412235
<cref>
2142-
I left off the scrolling parameters for this link. Technically,
2143-
the link should go to the page containing the specific "thing"
2144-
that is the context of the link. If the collection is using
2145-
semantic sorting, then this is do-able (ideally setting
2146-
the page boundary such that this is the first item, and allowing
2147-
input on the page count / "limit" parameter). But getting into
2148-
semantic scrolling/pagination seems way too involved for this
2236+
It's not clear how pagination should work with the link from the
2237+
entry point resource or the "collection" link in the item.
2238+
Technically, link from an item to a paginated or filtered
2239+
collection should go to a page/filter that contains the link
2240+
context. If the collection is using semantic sorting instead
2241+
of a plain integer limit and offset, then this is possible.
2242+
But getting into semantic pagination seems way too involved for this
21492243
example.
21502244
</cref>
21512245
</t>
@@ -2160,24 +2254,16 @@ Link: <https://api.example.com/trees/1/nodes/456> rev=up
21602254
</cref>
21612255
</t>
21622256
<t>
2163-
But what if we do not have any "thing"s yet? We cannot get to the
2164-
individual "thing" schema as there is no individual "thing" to fetch.
2165-
And the "tag:rel.example.com,2017:thing" link in the entry point
2166-
resource does not indicate how to create a "thing". The "self" link
2167-
requires the "id" to already exist, but it is assigned by the server.
2168-
So we need to add another link to our entry point schema:
2257+
Let's also update our entry point link to include pagination, specifically
2258+
allowing arbitrary input to choose the page:
21692259
</t>
21702260
<figure>
2171-
<preamble>
2172-
This LDO would be added to the top-level "links" array in the entry
2173-
point resource's hyper-schema.
2174-
</preamble>
21752261
<artwork>
21762262
<![CDATA[{
21772263
"rel": "tag:rel.example.com,2017:thing-collection",
21782264
"href": "/things{?offset,limit}",
21792265
"hrefSchema": {
2180-
"$ref": "thing-collection#/definitions/scrolling"
2266+
"$ref": "thing-collection#/definitions/pagination"
21812267
},
21822268
"submissionSchema": {
21832269
"$ref": "thing#"
@@ -2188,22 +2274,10 @@ Link: <https://api.example.com/trees/1/nodes/456> rev=up
21882274
}]]>
21892275
</artwork>
21902276
<postamble>
2191-
Now we see the scrolling parameters being accepted as input, so
2192-
we can jump to any scroll window within the collection.
2277+
Now we see the pagination parameters being accepted as input, so
2278+
we can jump to any page within the collection.
21932279
</postamble>
21942280
</figure>
2195-
<t>
2196-
<cref>
2197-
Here we also see the "submissionSchema" to use to create a "thing",
2198-
but how do we recognize it? We can't use a "collection" link relation
2199-
here, because there is no identifiable "thing" to serve as the context
2200-
resource. We could look at the submission schema, notice that it
2201-
has a "collection" link and is therefore an item, and notice that
2202-
its "collection" link produces the same(-ish?) URI, but that seems
2203-
overly complicated and also gets into trouble with query parameters
2204-
again.
2205-
</cref>
2206-
</t>
22072281
</section>
22082282
</section>
22092283

0 commit comments

Comments
 (0)