Pagination
This page collects design proposals for ISSUE-42. Proposals for the collection design in general can be found on the Collection Design page.
Current Design
{
"@id": "http://api.example.com/an-issue/comments?page=3",
"@type": "PagedCollection",
"firstPage": "/an-issue/comments",
"previousPage": "/an-issue/comments?page=2",
"nextPage": "/an-issue/comments?page=4",
"lastPage": "/an-issue/comments?page=498",
"member": [ ... ]
}
Pros:
- Simple and in line with what Atom and most HTML pages do
- Going from a non-paginated to a paginated collection only requires to add the pagination properties
Cons:
- By just getting the URL of a PagedCollection, it is unclear what was meant: just the members associated to that PagedCollection? The members from all interlinked PagedCollections? The property referencing a PagedCollection would need to define that.
Proposed Designs
Page, pageOf, and hasPage
Rename PagedCollection to Page and introduce two new properites pageOf and hasPage. A paginated collection would then look as follows in JSON-LD
{
"@id": "http://api.example.com/an-issue/comments?page=3",
"@type": "Page",
"previousPage": "/an-issue/comments?page=2",
"nextPage": "/an-issue/comments?page=4",
"pageOf": {
"@id": "http://api.example.com/an-issue/comments",
"@type": "Collection",
"firstPage": "/an-issue/comments?page=1",
"hasPage": "/an-issue/comments?page=4",
"lastPage": "/an-issue/comments?page=498"
},
"member": [ ... ]
}
Pros:
- It becomes possible to address the whole collection as well as individual pages.
Cons:
- Two new properties
- The previous/next links are split from the first/last page links
PartialCollection
Another design I have been tinkering with was to rename PagedCollection to something like PartialCollection and *perhaps* move the pagination controls into a separate resource or blank node:
{
"@id": "http://api.example.com/an-issue/comments?page=3",
"@type": "PartialCollection",
"pagination": {
"firstPage": "/an-issue/comments",
"previousPage": "/an-issue/comments?page=2",
"nextPage": "/an-issue/comments?page=4",
"lastPage": "/an-issue/comments?page=498"
},
"member": [ ... ]
}
Pros:
- Name makes it more explicit that the complete collection is meant. If something else is meant, this needs to be made explicit in the definition of the referencing property
Cons:
- An additional property (if we decide to introduce it; the proposal could also work without the pagination property even though it is not a cleanly modeled in that case
Just Collection
An alternative approach would be to get rid of separate collection types altogether and just have a single Collection class. This would mean that there's always a sequence of collections but if there's just one, there's obviously no need to link to others. The proposal would be to:
- remove the type PagedCollection
- rename itemsPerPage to numberItems
- optional: drop the "Page" suffix from firstPage, nextPage, previousPage, lastPage
A paginated collection would then look as follows:
{
"@id": "http://api.example.com/an-issue/comments?whatever=3",
"@type": "Collection",
"first": "/an-issue/comments",
"previous": "/an-issue/comments?whatever=2",
"next": "/an-issue/comments?whatever=4",
"last": "/an-issue/comments?whatever=498",
"member": [ ... ]
}
Pros:
- Reduces number of concepts and makes collections more uniform
Cons:
- No way to explicitly link to a specific page. A client would always be expected to fetch the all "pages" of a collection unless it finds the data it was looking for earlier.
PartialCollectionView
The main difference of this proposal is to look at pages of a collection as specific views on a single underlying collection instead of thinking of the collection as the sum of its pages. A representation of a specific view would look as follows:
{
"@id": "http://api.example.com/an-issue/comments",
"@type": "Collection",
"member": [ ... ],
"view": {
"@id": "/an-issue/comments?page=3",
"@type": "PartialCollectionView",
"first": "/an-issue/comments?page=1",
"previous": "/an-issue/comments?page=2",
"next": "/an-issue/comments?page=4",
"last": "/an-issue/comments?page=498",
}
}
Pros:
- Makes collections uniform
- The collection members are directly associated to the collection itself, not the view
- It's possible to point to both the complete collection as well as a specific view
- Opens the door to define views which are defined in terms of an offset and limit instead of a server defined "page"
- Can be generalized to other use cases
Cons:
- Looking at pages as "views" on the underlying collection might be unfamiliar or too abstract for lots of developers