All Articles

Offset based pagination in GraphQL-ruby

What will you do when a API fetches more that 100 records or more that 1000 records?

The first instinct of a developer is to add pagination to the API. Adding pagination restricts the amount of records fetched in single query.

The next question is, how to add pagination to GraphQL query?

Pagination can be added in two ways:

Adding offset based pagination is the simplest solution. The SQL query needs to be told how many records to skip(i.e: offset) and how many to be fetched from collection(i.e: limit). It is that easy.

Let’s understand how to add offset based pagination the Rails and GraphQL-ruby. First, let add a resolver to fetch all Post from database.

# app/graphql/resolvers/posts/index.rb

class Resolvers::Posts::Index < GraphQL::Schema::Resolver
  description "List of all the posts"

  type [Types::PostType], null: false

  def resolve
    Post.all
  end
end

To add offset based pagination, query needs to input the arguments from the application(i.e: offset and limit). Let’s add InputObjectAttributes for adding arguments to the query.

# app/graphql/input_object_attributes/offset_attributes.rb

class InputObjectAttributes::OffsetAttributes < Types::BaseInputObject
  description "Attributes for pagination"

  argument :limit, Integer, required: true
  argument :offset, Integer, required: true
end

The last thing we need to do is update the posts index query to accept the offset argument and update the query to fetch current page records only.

# app/graphql/resolvers/posts/index.rb

class Resolvers::Posts::Index < GraphQL::Schema::Resolver
  description "List of all the posts"

  argument :offset_attributes,
           InputObjectAttributes::OffsetAttributes,
           required: true

  type [Types::PostType], null: false

  def resolve(offset_attributes:)
    offset_params = offset_attributes.to_h

    Post.limit(offset_params[:limit]).offset(offset_params[:offset])
  end
end

And pagination is added. Fire up your graphiql or graphql-playground and try following query:

query FetchPosts {
  posts(offsetAttributes: { limit: 10, offset: 20 }) {
    id
    title
    content
  }
}

Offset based pagination has its disadvantages. Read more about Pagination: You’re (Probably) Doing It Wrong.

Happy Coding!!