A framework for DRY RESTful APIs in Ruby on Rails.
The Problem: Building controllers for APIs usually involves writing a lot of redundant CRUD logic, and routing them can be obnoxious. Building and maintaining features like ordering, filtering, and pagination can be tedious.
The Solution: This framework implements browsable API responses, CRUD actions for your models, and features like ordering/filtering/pagination, so you can focus on building awesome APIs.
Website/Guide: rails-rest-framework.com
Demo API: rails-rest-framework.com/api/demo
Source: github.com/gregschmit/rails-rest-framework
YARD Docs: rubydoc.info/gems/rest_framework
Add this line to your application’s Gemfile:
gem "rest_framework"
And then run:
bundle install
This section provides some simple examples to quickly get you started using the framework.
For the purpose of this example, you’ll want to add an api_controller.rb
to your controllers, as well as a directory for the resources:
controllers/
├─ api_controller.rb
└─ api/
├─ root_controller.rb
├─ movies_controller.rb
└─ users_controller.rb
The root ApiController
can include any common behavior you want to share across all your API controllers:
class ApiController < ApplicationController
include RESTFramework::BaseControllerMixin
# Setting up a paginator class here makes more sense than defining it on every child controller.
self.paginator_class = RESTFramework::PageNumberPaginator
# The page_size attribute doesn't exist on the `BaseControllerMixin`, but for child controllers
# that include the `ModelControllerMixin`, they will inherit this attribute and will not overwrite
# it.
class_attribute(:page_size, default: 30)
end
A root controller can provide actions that exist on the root of your API.
It’s best to define a dedicated root controller, rather than using the ApiController
for this purpose, so that actions don’t propagate to child controllers:
class Api::RootController < ApiController
self.extra_actions = {test: :get}
def root
return api_response(
{
message: "Welcome to the API.",
how_to_authenticate: <<~END.lines.map(&:strip).join(" "),
You can use this API with your normal login session. Otherwise, you can insert your API
key into a Bearer Authorization header, or into the URL parameters with the name
`api_key`.
END
},
)
end
def test
return api_response({message: "Hello, world!"})
end
end
And here is an example of a resource controller:
class Api::MoviesController < ApiController
include RESTFramework::ModelControllerMixin
self.fields = [:id, :name, :release_date, :enabled]
self.extra_member_actions = {first: :get}
def first
# Always use the bang method, since the framework will rescue `RecordNotFound` and return a
# sensible error response.
return api_response(self.get_records.first!)
end
def get_recordset
return Movie.where(enabled: true)
end
end
When fields
is nil, then it will default to all columns.
The fields
attribute can also be a hash to include or exclude fields rather than defining them manually:
class Api::UsersController < ApiController
include RESTFramework::ModelControllerMixin
self.fields = {include: [:calculated_popularity], exclude: [:impersonation_token]}
end
Use rest_route
for non-resourceful controllers, or rest_resource
/ rest_resources
resourceful routers.
These routers add some features to the Rails builtin resource
/resources
routers, such as automatically routing extra actions defined on the controller.
To route the root, use rest_root
.
Rails.application.routes.draw do
# If you wanted to route actions from the `ApiController`, then you would use this:
# rest_root :api # Will find `api_controller` and route the `root` action to '/api'.
namespace :api do
rest_root # Will route `Api::RootController#root` to '/' in this namespace ('/api').
rest_resources :movies
rest_resources :users
end
end
After you clone the repository, cd’ing into the directory should create a new gemset if you are using RVM.
Then run bin/setup
to install the appropriate gems and set things up.
The top-level bin/rails
proxies all Rails commands to the test project, so you can operate it via the usual commands (e.g., rails test
, rails server
and rails console
). For development, use foreman start
to run the web server and the job queue.