Building a Production Ready Rails JSON API

Configuring Rails as a JSON API

Learn how to configure Ruby on Rails as a JSON API that accepts and responds with camelCase parameters.

Configuring Routes for the API

Our JSON API will be authenticated using JWT tokens, so we wont need Rails's CSRF protection to throw an exception when the CSRF token is missing, we'll instruct Rails to use a null session instead. Since the JWT token must be added to requests manually using Javascript, we don't need to worry about the browser automatically sending cookies to our server (since we're not using cookies for sessions) to forge one of our user's sessions on a different domain.

Use a null session to protect from CSRF

In app/controllers/application_controller.rb, update protect_from_forgery with: :exception to protect_from_forgery with: :null_session.

CSRF is usually checked on non-GET requests, and by default if no CSRF token is provided Rails will throw an exception, causing our requests to fail. The :null_session setting will clear out our session variables instead of causing an exception to be thrown.

Finally, per the API spec we're adhering to, we want our clients to be able to submit their payloads using lowerCamelCase and our responses should be lowerCamelCase as well. Since we'll be using Jbuilder for rendering JSON responses, we can use an initializer to configure Jbuilder to output all JSON keys in lowerCamelCase.

Configure Jbuilder to output keys in lowerCamelCase

Create an initializer in config/initializers/jbuilder.rb with the following code:

Jbuilder.key_format camelize: :lower

In order to keep using snake_case throughout our app, we'll have to convert any incoming parameters in our application to snake_case. This can be achieved by using a before_action filter in application_controller.rb

Create a filter to convert incoming parameters to snake_case

Create the following private method in application_controller.rb

  def underscore_params!

Then, use a before_action filter in application_controller.rb to apply the filter to every request.

  before_action :underscore_params!

Changing our parameters to snake_case has a couple advantages, it keeps our code looking clean and Ruby-ish (instead of having to reference lowerCamelCase parameters), and it allows us to pass our parameters to model methods like update_attributes on our models without having to worry about case conversion.

Configure controllers to respond to json requests

Add respond_to :json after the protect_from_forgery line in ApplicationController

This configuration ensures our controllers will respond with the correct MIME type and enables 3rd party controllers in gems (like Devise controllers) to respond using JSON.