-
Notifications
You must be signed in to change notification settings - Fork 896
Feat: Use only one standardized method for pagination across the API #1358
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
Comments
We actually originally were only going to support cursor pagination, but then it's quite challenging to make pages work. Offset pagination makes "Jump to page 10" really easy, which is great for the UI. I see cursor pagination critical for streaming data, as the offset pagination would cause issues. If you consider our data, offset pagination for the UI is sufficient in almost every case. The risk of race conditions is not a big deal in the UI in that 0.1% case of viewing the users page. Github actually does this for their repos, orgs, and user pages. (https://github.com/orgs/coder/repositories?page=2&type=all) The only one that I can think of that would prefer cursor based is audit logs, since that is a data stream. Now for a script, offset pagination is potentially risky, as in the edge case a new user is made while paging, you might skip someone. That is why I added a
The logic was that offset is sufficient for all ui purposes, but our customers do consume our api for automating various tasks. In that automation case, we need a way to paginate in a single direction that does not have race conditions. This was also taken from Github. In summary, I do agree cursor based pagination is more correct, but for usability, offset pagination is much easier to work with in a UI. If we decide to do cursor based pagination, the UI would probably have to do something like call the next 2 pages, the previous 2 pages, and the last(?) page for the UI to show For the audit log case though, I'm cool with making that cursor based. (Sorry was on PTO during a lot of this talk) |
Another comment on See all the issues on their repo:
And PRS:
(probably more) |
The concern I have is setting up potential future developers for shooting themselves in the foot by writing scripts that use offset-paging. If cursor pagination is difficult for the UI, then perhaps we can mitigate the above concern in some other way. Some ideas:
|
Do you think that is something that can be handled in our api documentation? The only way a user would know We could also not even document the |
I appreciate your input on this issue @Emyrk, you raise some very good points. Based on your comments I think we should keep both around like you originally designed it. We can either close this issue or re-purpose it for tracking improvements (total pages, split structs [see below]?). I'd like to point out that currently the offset pagination is fairly discoverable in the SDK, but I don't think that should be a problem as long as we document it properly, maybe add a What are your thoughts about splitting Lines 10 to 27 in 64a8b4a
I also think @spikecurtis suggestion for having separate URLs/parameters for UI is pretty neat, but might be problematic to express in both SDK and generated typings. It's too bad about |
I'm ok with splitting it up into 2 structures, and throwing an error if you mix and match. I have no strong feelings on that. The returned urls for the next/prev page are nifty. I was doing that originally when I had cursor pagination instead, and just also returned the appropriate data needed to make the url. If you just return the url, it is kinda annoying for an sdk to consume. {
// Data is the general "data" or "error" top level field
"data": {
// page is the list of paged data. Each object in the paged
// data set is an object.
"page": [{}, {}],
"pager": {
// A page is a list of elements of length 'limit'.
// The first element is index '0'.
// "ending_before" == page[0]
// The last element is index `-1` (last element)
// "starting_after" == page[-1]
"ending_before": "<before_uuid>",
"starting_after": "<after_uuid>",
// next_uri is the path to fetch the next page of users.
// "" if there is no next page
"next_uri": "/api/v2/users?after=<after_uuid>&limit=10"
// previous_uri returns the orevious page
// "" if there is no previous page
"previous_uri": "/api/v2/users?before=<before_uuid>&limit=10",
// Limit is the maximum number of elements that will be returned in
// 1 page.
"limit": 10,
}
}
} |
We should treat the SDK as a public API, just like the HTTP API. We're going to open source the repo, and so anyone writing go code to interact programmatically with a coder server can and should use the SDK. |
Can we base this decision on prior art? I'm used to simpler APIs like this. We will not generate client bindings for every programming language, and many will use |
@ammario you can find examples of offset and cursor pagination in all enterprise products that I have seen. Github uses a mix for example. It's a decision we should make based on our needs. I believe we can get a better UI experience with offset pagination. If the UI team doesn't think "Jump to page X" and showing the page numbers at the bottom is useful, then I have no issue with cursor based pagination for all things. |
@Emyrk @spikecurtis @mafredri @presleyp are we in agreement that we should keep the original implementation, with some modifications that @Emyrk suggested further in the thread? If we are going to diverge from the original implementation, it should probably be decided sooner rather than later as it will have downstream implications. But if we are going to keep the original, perhaps with modifications, then it seems like this could safely come after the Community launch. |
Depends on our stance re: back compatibility of our APIs after Community Launch. If we're willing to break stuff, we can punt for now and revisit. If we're not willing to break people's code, then we kinda need to decide now. @tjcran |
The major business risk is not delivering fast enough to make an amazing launch. After we do that and begin accumulating a user base, we should look at stabilizing some APIs. |
Closing this issue because the decision was made that we would keep status quo for now in how Pagination is already implemented. |
Uh oh!
There was an error while loading. Please reload this page.
What is your suggestion?
We should only use one standardized method of pagination across the API, preferably we'd keep the cursor based pagination and drop support for
offset
.Another approach would be to return pagination metadata in the API responses, for instance, something like:
Why do you want this feature?
This was discussed in #1308 and @spikecurtis had good motivations for only keeping one (#1308 (comment)), according to @presleyp it may suffice to only keep cursor based pagination around (#1308 (comment)).
Having two methods for pagination can be confusing and hard to enforce on the API side across all endpoints. It might also add complexity if we introduce more advanced features, like sorting on column.
I think it would be good if @Emyrk had a chance to give his two cents as developer of the original implementation.
The issue described in #1357 may also need to be considered here.
Are there any workarounds to get this functionality today?
No.
Are you interested in submitting a PR for this?
After we have consensus on what approach to take? Sure.
The text was updated successfully, but these errors were encountered: