Anchors, position and keyset pagination

30 views
Skip to first unread message

Robert Stepanek

unread,
Jul 20, 2016, 3:07:26 AM7/20/16
to JMAP
This is not ripe for a pull request, but I'd like to instigate discussion about getFooList pagination.

Currently, all getFooList methods define a position and limit property (and their responses a total) to allow clients to paginate search results. That's vanilla pagination, but it has the drawback that in order to compute page x, all x-1 search results must be (re)determined. Servers might try to cache search results, with all the burdens of statefulness.

In contrast, a nextPageToken might help server implementations to reduce search space and speed up response time without keeping state. A nice write-up for this method is here: http://use-the-index-luke.com/no-offset

If there is willingness to support this for the getFooList methods, off the top of my head I'd see these options:

- Add nextPageToken as properties to both the requests and responses. A null pageToken indicates the first page for requests, and the end of pages in the response. Clients may choose to use either offset-based or keyset pagination.

- Same as first option, but deprecate offset-based pagination.This would work under the assumption, that clients do not arbitrarily choose positions and limits, but cycle through pages from start to finish. In this case, existing server implementation could calculate their nextPageToken with the total index of the first element in the current page plus limit. (*)

Note that the getMessageList method already defines two different pagination types (position and anchors) whereas contacts and calendarEvents only support offset-based pagination. I understand (and appreciate) the ambition to keep the spec small, but I wonder if the current offset-based pagination isn't unnecessarily restrictive for implementations.

What do you think?

(*) Disclaimer: I haven't prototyped this yet, so behind this alluring scheme might be a serious flaw lurking.



Neil Jenkins

unread,
Jul 20, 2016, 3:43:45 AM7/20/16
to JMAP Mailing List
On Wed, 20 Jul 2016, at 05:07 PM, Robert Stepanek wrote:
In contrast, a nextPageToken might help server implementations to reduce search space and speed up response time without keeping state. A nice write-up for this method is here: http://use-the-index-luke.com/no-offset
 
The reason we have position+limit (and the total is always returned) is so that a client can simulate having the whole mailbox loaded, without actually having to load the whole mailbox. If the user grabs the scrollbar they can jump to an arbitrary point, and the client can intelligently load in just the data in that page. This can only work using a position.
 
This is simply not possible with the token style paging. Now, you could implement it as well as the position so the client could use either, but frankly that just makes the protocol more complicated without enhancing what you can do with it so I'm not really in favour.
 
Note that the getMessageList method already defines two different pagination types (position and anchors) whereas contacts and calendarEvents only support offset-based pagination.
 
This is there to support a very specific use case: finding the index of a particular item in the list. This lets you restore state from a URL or other serialisation mechanism. It's there because it provides significant extra functionality. Maybe it should be on the other types as well for consistency, although this then adds complexity (I think it's less likely to be useful in the other contexts – contacts will often be loaded in their entirety so the client can find the index, and calendars normally save the date you're looking at as the state rather than an event; the need to expand recurrences client-side anyway makes the index in the list less useful in general).
 
Neil.

Robert Stepanek

unread,
Jul 20, 2016, 4:21:45 AM7/20/16
to jmap-d...@googlegroups.com
On Wed, Jul 20, 2016 at 9:43 AM, Neil Jenkins <ne...@fastmail.com> wrote:
> The reason we have position+limit (and the total is always returned) is so
> that a client can simulate having the whole mailbox loaded, without actually
> having to load the whole mailbox.

Thanks for the explanation. Make sense to me.

> contacts will often be loaded in their
> entirety so the client can find the index, [...] the need to expand [calendar event]
> recurrences client-side anyway makes the index in the list less useful in
> general).

This is why I fail to see the benefit of offset-based paging for
contacts and calendar events, Of course, being consistent across
object type search might be a good enough argument not to use token
style paging. Yet, from your experience having implemented a JMAP
client for all object types is there really a use-case for
server-side, offset-based paging for contacts or calendar events
(that's a genuine question, no subtlety here)? Token-based pagination
looks like a more lightweight scheme for both clients and servers, and
doesn't seem to dictate as many implementation details, but I might be
mistaken here.

Any way, I'd be happy to see it in the spec but am not pushing for it.
There's always the option to fall back to a x-nextPageToken property
for tightly bound client and server implementations that might benefit
from it.

Cheers,
Robert

Neil Jenkins

unread,
Jul 20, 2016, 7:29:35 AM7/20/16
to JMAP Mailing List
On Wed, 20 Jul 2016, at 06:21 PM, Robert Stepanek wrote:
This is why I fail to see the benefit of offset-based paging for
contacts and calendar events, Of course, being consistent across
object type search might be a good enough argument not to use token
style paging.
 
Yes, I think consistency is a stronger argument than possible implementation efficiency here. Consistency makes both server and client implementations easier.
 
Yet, from your experience having implemented a JMAP
client for all object types is there really a use-case for
server-side, offset-based paging for contacts or calendar events
(that's a genuine question, no subtlety here)?
 
Not in our implementation, no. But then the token-based paging wouldn't be any more efficient either, because in both of these cases our client wants the whole set – no paging required! (In the case of calendar, it actually is paging it in by date range, but in JMAP terms that's a series of different CalendarEventList queries, each of which is fetched in its entirety and not paged in by the client).
 
Neil.
Reply all
Reply to author
Forward
0 new messages