Easy API pagination for Rails
API Pagination done right. Pager API is a library to help you add meta
information and the adequate header with pagination information based on the JSON API standard for your Rails app.
pager_api
depends on Pagy, Kaminari, WillPaginate to handle pagination. You need to add one of these gems to your Gemfile before the pager_api
gem:
# gem 'will_paginate'
# gem 'kaminari'
# gem 'pagy'
gem 'pager_api'
And then execute:
% bundle
This step is totally optional
The gem comes with an installer for you to configure it, for example to switch between pagination handlers or whether or not to include the Link
header or meta information. To install it you just need to run:
% rails g pager_api:install
This will create a file under the initializers
directory called pager_api.rb
. You can easily configure it there to meet your needs.
By default pager_api
uses Pagy. Configure the pager_api.rb
initializer in order to use WillPaginate or Kaminari.
We highly recommend you use Active Model Serializers for rendering your JSON responses
Currently the pager-api
gem needs some configuration to work nice with
Active Model Serializers, just add a file under config/initializers
on
your rails project:
% touch config/initializers/active_model_serializers.rb
And a this line:
ActiveModelSerializers.config.adapter = :json
Or even
ActiveModelSerializers.config.adapter = :json_api
In the controller where you are providing a paginated collection, you may have something like this:
class UsersController < ApplicationController
def index
users = User.page(params[:page]).per(15)
render json: users,
meta: {
pagination: {
per_page: 15,
total_pages: 10,
total_objects: 150
}
}
end
end
With pager_api
it is really easy to achieve the above by:
class UsersController < ApplicationController
def index
# You can have any scope for the User class in this case
# You can even send the paginated collection
paginate User.unscoped, per_page: 15
end
end
This will output a json object like:
{
"users": [
...
],
"meta": {
"pagination": {
"per_page": 15,
"total_pages": 1,
"total_objects": 15,
"links": {
"first": "/api/users?page=1",
"last": "/api/users?page=1"
}
}
}
}
As you can see, the pagination metadata also includes the links information for the first
and last
page, but it will also create the next
and the prev
keys when necessary.
By default it will also include a Link
header with the following information:
# Link: <http://example.com/api/v1/users?page="2">; rel="next",
# <http://example.com/api/v1/users?page="5">; rel="last",
# <http://example.com/api/v1/users?page="1">; rel="first",
# <http://example.com/api/v1/users?page="1">; rel="prev",
The header will be created with the corresponding first
, last
, prev
and next
links.
Have a bug or a feature request? Please open a new issue. Before opening any issue, please search for existing issues.
Please submit all pull requests against a separate branch. Although pager_api
does not have tests yet, be a nice guy and add some for your feature. We’ll be working hard to add them too.
In case you are wondering what to attack, we have a milestone with the version to work, some fixes and refactors. Feel free to start one.
Thanks!
Abraham Kuri
Code and documentation copyright 2015 Icalia Labs. Code released under the MIT license.