Pagination

From Hydra Community Group

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