Skip to content

Pagination using Range cannot be consistent #87

Closed
@KellerFuchs

Description

@KellerFuchs

Section 1.6 and the Heroku API reference both recommend using Range for pagination.

Using the Range/Next-Range mechanism from HTTP accidentally exposes in the API that the data is (likely) obtained by computing the requested data within a selected window; for instance, for a query that exposes data from a SQL database:

SELECT * FROM table WHERE condition ORDER BY field LIMIT (#page * size), size

Moreover, this implementation pattern cannot provide a consistent view of the data when concurrent actions can introduce new elements at arbitrary indexes. Consider the following sequence of events:

  1. client requests the data, gets a partial answer with the first 10 elements and Next-Range: 20 ..; let's call the elements e0 to e9;
  2. a concurrent query triggers the insertion of elements x and y at indexes 9 and 14;
  3. the client requests the next page, and receives e10 = e9, e11 ... e19: e9 has been seen twice by the client (unless you use id-based pagination), and it saw y but not x (despite them having been added simultaneously, regardless of whether you use id-based pagination).

The right solution is to provide the API client with a consistent view of the data; for APIs returning results of DB queries, this is easily done using either cursors or materialized views, the second having the additional advantage of supporting later refinement queries.

At the API level, this should be materialized using the Link header, with (at least) a reference tagged rel=next. Using Link allows the API implementer to store there whatever is required to designate the right query result (for instance, a DB cursor id).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions