Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add explicit link to next page of results in search API #7841

Open
robertknight opened this issue Feb 6, 2023 · 6 comments
Open

Add explicit link to next page of results in search API #7841

robertknight opened this issue Feb 6, 2023 · 6 comments

Comments

@robertknight
Copy link
Member

The search API supports cursor-based pagination using the search_after parameter. The responses do not include an explicit link to the next page of results, so API clients have to figure out how to construct that themselves, and also how to tell when they have reached the end of the results. This has caused some problems:

  • The lack of explicit "last page" indicator and an h issue with deleted annotations caused a client bug where in some rare cases it only fetches a subset of the annotations it should
  • I have fielded several queries from users who had problems using search_after because they did not construct the next-page link correctly, or got confused by the fact that "after" refers to the order of entries in the results, and not necessarily "after" in a chronological sense. Providing an explicit link would avoid the need for manual construction for the most common use case, and also provide a live example of how the parameter is used.

What I would suggest we do is add an explicit "next page" link to the results, which is omitted for the last page. Some examples in other APIs:

Of the approaches above, I think I would favor a field in the JSON response, as being easier to discover and to parse.

@acelaya
Copy link
Contributor

acelaya commented Feb 7, 2023

+1 to the _links approach. I agree it's easier to discover. Anyone debugging the API will quickly find about it, as the response body is what one usually inspects first when messing around with an API.

I've also seen that more often.

@robertknight
Copy link
Member Author

The Confluence API is similar to https://stateless.co/hal_specification.html (see also https://datatracker.ietf.org/doc/html/draft-kelly-json-hal-08), but slightly different, as link values are just strings, as opposed to objects in the HAL spec.

@robertknight
Copy link
Member Author

Some more resources:

Blog post about different ways of embedding links in APIs: https://evertpot.com/json-links/
JSON API profile for cursor pagination: https://jsonapi.org/profiles/ethanresnick/cursor-pagination/#profile-intro.

robertknight added a commit to hypothesis/client that referenced this issue Feb 7, 2023
There is currently an issue in h where the search API call may sometimes return
pages that are incomplete, even if there are more pages of results to fetch
afterwards [1]. A non-full page caused the client to stop fetching more pages as
it incorrectly assumed it had reached the end. Ultimately this needs to be
resolved in the API [2] by adding an explicit next-page link. Until that is done,
change the client to continue paging through results as long as the current page
has at least one entry (needed to construct the cursor) and we expect more
results based on the `total` value in the response.

Fixes #5219

[1] hypothesis/h#7840
[2] hypothesis/h#7841
robertknight added a commit to hypothesis/client that referenced this issue Feb 7, 2023
There is currently an issue in h where the search API call may sometimes return
pages that are incomplete, even if there are more pages of results to fetch
afterwards [1]. A non-full page caused the client to stop fetching more pages as
it incorrectly assumed it had reached the end. Ultimately this needs to be
resolved in the API [2] by adding an explicit next-page link. Until that is done,
change the client to continue paging through results as long as the current page
has at least one entry (needed to construct the cursor) and we expect more
results based on the `total` value in the response.

Fixes #5219

[1] hypothesis/h#7840
[2] hypothesis/h#7841
robertknight added a commit to hypothesis/client that referenced this issue Feb 8, 2023
There is currently an issue in h where the search API call may sometimes return
pages that are incomplete, even if there are more pages of results to fetch
afterwards [1]. A non-full page caused the client to stop fetching more pages as
it incorrectly assumed it had reached the end. Ultimately this needs to be
resolved in the API [2] by adding an explicit next-page link. Until that is done,
change the client to continue paging through results as long as the current page
has at least one entry (needed to construct the cursor) and we expect more
results based on the `total` value in the response.

Fixes #5219

[1] hypothesis/h#7840
[2] hypothesis/h#7841
@kael
Copy link

kael commented May 23, 2023

Some examples in other APIs:

There's also a possible use of the HTTP Range header field - although not sure it completely fits the requirements.

From Range header, I choose you (for pagination)! :

  • Querying the root of the collection :
GET /users

200 OK
Accept-Ranges: users
Content-Range: users 0-9/200

[ 0, …, 9 ]
  • Requesting past the end of the collection :
GET /users
Range: users=1000-

416 Requested Range Not Satisfiable
  • Last-n requests :
GET /users
Range: users=-5

206 Partial Content
Accept-Ranges: users
Content-Range: users 195-199/200

[ 195, …, 199 ]

Pity there's no standard JS API for parsing <Link/> headers.

@kael
Copy link

kael commented May 24, 2023

There's also a possible use of the HTTP Range header field - although not sure it completely fits the requirements.

It does not fit the requirements, indeed. I was a bit too happy to get all informations using a HEAD request, but it's not easily parsable out-of-the box

(I'm querying the API to get the total count of annotations per URI using limit=0, I was thinking that a HEAD could replace it).

@kael
Copy link

kael commented Sep 11, 2023

What I would suggest we do is add an explicit "next page" link to the results, which is omitted for the last page.

It'd be interesting to include the first and last annotations of the whole result.

With pagination, to be able to display next and previous buttons, for a query I'm also fetching the first (order=asc&limit=1) and last (order=desc&limit=1) annotations so that if the first annotation of the whole result is equal to the first annotation of the annotations slice the next <button/> is disabled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants