When you use the API to get the commits for a repo (/api/v3/projects/:id/repository/commits), the result is paginated but there is Link header added to the response headers.
Is this done explicitly to avoid some performance issues or can this still be implemented?
Designs
Child items
...
Show closed items
Linked items
0
Link issues together to show that they're related or that one is blocking others.
Learn more.
It appears the source of the issue is an incompatibility between the way the array of commits is generated at the /projects/:id/repository/commits endpoint and the way plain arrays are usually paginated with Kaminari.paginate_array. The code for this particular route lives here.
Let's take a look at the last line of the method that presents the response.
That fails, however, because commits is a flat array. Kaminari extends ActiveRecord::Relation and ActiveRecord::Model with #page, and the paginate helper expects its argument to respond to that method. Luckily, there is a convenience method: Kaminari.paginate_array to wrap an array into a pageable object. Something like this may suffice:
And here we run into the crux of the issue. With the above changes you do get a Link header, but the parameters are incorrect. For instance, a request like
GET /api/v3/projects/8/repository/commits?page=1&per_page=20
receives this response (only relevant headers shown):
Most notably, X-Total says there are only 20 commits in this repository. Clearly that is not true. I can perform the same request with a per_page parameter set to 100 and I'll get more commits. This is because our working solution reuses the same pagination parameters to construct the commit range array as it uses to paginate the array. That way, the array's size is the same as per_page, and there's always only one page. You will, for example, receive an empty body if you try to access the second page:
GET /api/v3/projects/8/repository/commits?page=&per_page=20