RESTful API using Rails: what I learned

Recently I have to build a JSON API to wrap the connection to persistence layer in order to be able to change (or add) DBMS later and define more structured logic (authentication, selective caching, …). I didn’t know which DBMS to use but I had to start develop the other components which relay on this persistence layer.

To avoid delay while choosing DBMS setup we decided to build a prototype using Rails and MySQL in order to start defining API’s methods. Rails is really useful when you had to create a MVC application but includes too much stuff if you only need to build an API. This is why usually we use Sinatra.

This time we tried Rails::API,  a subset of a normal Rails application. It’s a bit faster and lightweight and you can use your existing Rails app.

To use it you only need to add gem to Gemfile:

gem 'rails-api'

change the ancestor of ApplicationController

class ApplicationController < ActionController::API
# [...]
end

and comment out the protect_from_forgery call if you are using it.

Everything seems to be ok. Created four models, a couple of controllers with usual REST action and everything is done: my prototype is up and running.

Unfortunately there are some new Rails feature that aren’t well supported by this gem. The most important is the wrap_parameters support IMHO. The ActionController::ParamsWrapper should automatically make a copy of request’s parameters into an hash named as the element you are sending.

For example, if you send to /users:

{"name": "Andrea"}

controller should receive:

{"name" => "Andrea", "user" => {"name" => "Andrea"}}

It is very convenient if you use standard ActiveRecord-based scaffold but Rails::API doesn’t support well this initializer: https://github.com/rails-api/rails-api/issues/33. You have to setup it manually.

Into each controller you must define how to wrap params:

class UsersController < ApplicationController
wrap_parameters :person, include: [:name], format: :json
# [...]
end

Is the only issue i found but took me a lot of time to be solved. I choose Rails because is easy and I can build a prototype in a flash but I think is still to early to use it to build an API, maybe Rails 4. At the moment I still prefer to use Sinatra.

Thanks to @olinicola, he built the prototype and found the solution to the issue.