Skip to content

fabienpiette/fetcheable_on_api

Repository files navigation

FetcheableOnApi

JSONAPI-compliant filtering, sorting, and pagination for Rails API controllers, declared in two lines, zero boilerplate.


Gem Version Documentation License

Quick Start

Add the gem:

gem 'fetcheable_on_api'
bundle install
rails generate fetcheable_on_api:install

Declare what's allowed, then apply:

class UsersController < ApplicationController
  filter_by :name, :email, :status
  sort_by :name, :created_at

  def index
    render json: apply_fetcheable(User.all)
  end
end

Your API now supports:

GET /users?filter[name]=john&filter[status]=active
GET /users?sort=name,-created_at
GET /users?page[number]=2&page[size]=25
GET /users?filter[status]=active&sort=-created_at&page[number]=1&page[size]=10

Features

  • 30+ filter predicates, eq, ilike, between, in, gt, lt, and many more, plus custom lambdas
  • Multi-field sorting, comma-separated fields, +/- prefix for direction, case-insensitive option
  • Automatic pagination, page-based with response headers (Pagination-Current-Page, Pagination-Per, Pagination-Total-Pages, Pagination-Total-Count)
  • Association support, filter and sort through ActiveRecord associations
  • Whitelisted by design, only explicitly declared attributes are queryable

Install

Prerequisites: Ruby >= 2.7, Rails >= 5.2 (ActiveSupport >= 5.2, < 9)

Compatibility

Ruby Rails 5.2 Rails 7.0 Rails 7.1 Rails 7.2 Rails 8.0
2.7
3.0
3.1
3.2
3.3
3.4

Bundler (recommended)

# Gemfile
gem 'fetcheable_on_api'
bundle install
rails generate fetcheable_on_api:install

Manual

gem install fetcheable_on_api

Usage

Filtering

filter_by :name                          # default: ilike (partial, case-insensitive)
filter_by :email, with: :eq              # exact match
filter_by :age, with: :gteq             # numeric comparison
filter_by :created_at, with: :between, format: :datetime  # date range

Filter through associations:

filter_by :author, class_name: User, as: 'name'

Custom lambda predicates:

filter_by :full_name, with: ->(collection, value) {
  collection.arel_table[:first_name].matches("%#{value}%").or(
    collection.arel_table[:last_name].matches("%#{value}%")
  )
}
GET /users?filter[name]=john              # partial match
GET /users?filter[status]=active,pending  # multiple values (OR)
GET /users?filter[age]=21                 # numeric
GET /users?filter[author]=jane            # through association

Sorting

sort_by :name, :created_at
sort_by :display_name, lower: true                          # case-insensitive
sort_by :author, class_name: User, as: 'name'              # through association
GET /users?sort=name                # ascending
GET /users?sort=-created_at         # descending
GET /users?sort=status,-created_at  # multiple fields

Pagination

Pagination works automatically. Configure the default page size:

# config/initializers/fetcheable_on_api.rb
FetcheableOnApi.configure do |config|
  config.pagination_default_size = 50  # default: 25
end
GET /users?page[number]=2&page[size]=25

Response headers:

Pagination-Current-Page: 2
Pagination-Per: 25
Pagination-Total-Pages: 8
Pagination-Total-Count: 200

Combining Everything

class PostsController < ApplicationController
  filter_by :title, :published
  filter_by :author, class_name: User, as: 'name'
  sort_by :title, :created_at
  sort_by :author, class_name: User, as: 'name'

  def index
    render json: apply_fetcheable(Post.joins(:author).includes(:author))
  end
end
GET /posts?filter[author]=john&filter[published]=true&sort=-created_at&page[number]=1&page[size]=10

Documentation

Contributing

Contributions welcome. See CODE_OF_CONDUCT.md for community guidelines.

bin/setup          # install dependencies
rake spec          # run tests
bin/console        # interactive console

Acknowledgments

Thanks to all contributors.

Built on top of Arel and the JSONAPI specification.

License

MIT

About

JSONAPI-compliant filtering, sorting, and pagination for Rails API controllers, declared in two lines, zero boilerplate.

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors