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