Rails for API only applications
IMPORTANT: Rails::API has been merged into Rails
Rails::API is a subset of a normal Rails application, created for applications that don't require all functionality that a complete Rails application provides. It is a bit more lightweight, and consequently a bit faster than a normal Rails application. The main example for its usage is in API applications only, where you usually don't need the entire Rails middleware stack nor template generation.
This is a quick walk-through to help you get up and running with Rails::API to create API-only Apps, covering:
Traditionally, when people said that they used Rails as an "API", they meant providing a programmatically accessible API alongside their web application. For example, GitHub provides an API that you can use from your own custom clients.
With the advent of client-side frameworks, more developers are using Rails to build a backend that is shared between their web application and other native applications.
For example, Twitter uses its public API in its web application, which is built as a static site that consumes JSON resources.
Instead of using Rails to generate dynamic HTML that will communicate with the server through forms and links, many developers are treating their web application as just another client, consuming a simple JSON API.
This guide covers building a Rails application that serves JSON resources to an API client or client-side framework.
The first question a lot of people have when thinking about building a JSON API using Rails is: "isn't using Rails to spit out some JSON overkill? Shouldn't I just use something like Sinatra?"
For very simple APIs, this may be true. However, even in very HTML-heavy applications, most of an application's logic is actually outside of the view layer.
The reason most people use Rails is that it provides a set of defaults that allows us to get up and running quickly without having to make a lot of trivial decisions.
Let's take a look at some of the things that Rails provides out of the box that are still applicable to API applications.
While you could obviously build these up in terms of existing Rack middlewares, I think this list demonstrates that the default Rails middleware stack provides a lot of value, even if you're "just generating JSON".
redirect_to user_url(current_user)come in handy. Sure, you could manually add the response headers, but why?
Of course, the Rails boot process also glues together all registered components. For example, the Rails boot process is what uses your config/database.yml file when configuring ActiveRecord.
The short version is: you may not have thought about which parts of Rails are still applicable even if you remove the view layer, but the answer turns out to be "most of it".
If you're building a Rails application that will be an API server first and foremost, you can start with a more limited subset of Rails and add in features as needed.
NOTE: rails-api only supports Ruby 1.9.3 and above.
Install the gem if you haven't already:
gem install rails-api
Then generate a new Rails::API app:
rails-api new my_api
This will do two main things for you:
Rails includes all of the sub-frameworks (ActiveRecord, ActionMailer, etc) by default. Some API projects won't need them all, so at the top of config/application.rb, you can replace
require 'rails/all'with specific sub-frameworks:
# config/application.rb # require "active_record/railtie" require "action_controller/railtie" require "action_mailer/railtie" # require "sprockets/railtie" require "rails/test_unit/railtie"
This can also be achieved with flags when creating a new Rails::API app:
rails-api new my_api --skip-active-record --skip-sprockets
Note: There are references to ActionMailer and ActiveRecord in the various config/environment files. If you decide to exclude any of these from your project its best to comment these out in case you need them later.
# comment out this in config/environments/development.rb config.active_record.migration_error = :page_load config.action_mailer.raise_delivery_errors = false
comment out this in config/environments/test.rb
config.action_mailer.delivery_method = :test
If you want to take an existing app and make it a Rails::API app, you'll have to do some quick setup manually.
Add the gem to your Gemfile:
bundleto install the gem.
# instead of class ApplicationController < ActionController::Base end
class ApplicationController < ActionController::API end
And comment out the
protect_from_forgerycall if you are using it. (You aren't using cookie-based authentication for your API, are you?)
If you want to use the Rails default middleware stack (avoid the reduction that rails-api does), you can just add
config.api_only = falseto
We suggest using ActiveModel::Serializers to serialize your ActiveModel/ActiveRecord objects into the desired response format (e.g. JSON).
An API application comes with the following middlewares by default.
stale?feature in Rails controllers.
config.threadsafe!), this middleware will add a mutex around your requests.
Other plugins, including ActiveRecord, may add additional middlewares. In general, these middlewares are agnostic to the type of app you are building, and make sense in an API-only Rails application.
You can get a list of all middlewares in your application via:
Rails ships with a number of other middlewares that you might want to use in an API app, especially if one of your API clients is the browser:
Any of these middlewares can be added via:
If you don't want to use a middleware that is included by default in the API middleware set, you can remove it using config.middleware.delete:
Keep in mind that removing these features may remove support for certain features in ActionController.
An API application (using ActionController::API) comes with the following controller modules by default:
Other plugins may add additional modules. You can get a list of all modules included into ActionController::API in the rails console:
ActionController::API.ancestors - ActionController::Metal.ancestors
All Action Controller modules know about their dependent modules, so you can feel free to include any modules into your controllers, and all dependencies will be included and set up as well.
Some common modules you might want to add:
The best place to add a module is in your ApplicationController. You can also add modules to individual controllers.
git checkout -b my-new-feature)
git commit -am 'Added some feature')
git push origin my-new-feature)