We are rebuilding. Join us.

We are rebuilding our site—live at building.seesparkbox.com. Join us, real-time, as the site evolves. It will be ugly at times. Sometimes it will be downright broken. But it will always be transparent and real. You can even check under the hood of the public repo on Github and share your ideas. Crazy, are we? Read why we're doing this.

Let’s be more than friends.

We really
like to share

The Foundry is our place to share articles, tutorials, events, and more. Search for a topic or just read everything.

Better Rails APIs with RABL

Better Rails APIs with RABL

Web development is changing. It seems that every day I come across another Javascript framework. More than ever, I am spending time not writing partials or views––but defining APIs that my front-end code can use. It does not seem that Rails 'to_json' is the ideal solution for defining these API's that are becoming more complex.

How we have always done it

One thing that has always bothered me about the way we have always done it: JSON is becoming the new view in a world where server calls are becoming less frequent.

Typical rails controller

1 2 3 4 5 6 7 8 9 10 11
class RailsController < ApplicationController
respond_to :json
 
def index
@students = Student.all
respond_with(@students) do |format|
format.json { render :json => @students.to_json(:only => [:firstname, :lastname, :email, :phonenum])}
end
end
 
end

JSON Result

1 2 3 4 5 6 7 8 9 10 11 12 13 14
[
{
"email": "info@heysparkbox.com",
"firstname": "Drew",
"lastname": "Clemens",
"phonenum": "937-401-9501"
},
{
"email": "info@heysparkbox.com",
"firstname": "Andy",
"lastname": "Rossi",
"phonenum": "937-401-9501"
}
]
view raw rails_json.js This Gist brought to you by GitHub.

This is a simple example that does not have any includes or methods that need to be added from the model. This could quickly become a very large block of code in the controller. This does not feel like controller code to me; I have always wanted to push this code to the view. Until recently, I only ever had a few places where this was an issue so I ignored it. More and more it seems like our JSON API's are growing. In some cases most of the view rendering is taking place in JavaScript. I want and need more control over my JSON, as it is becoming the major contract in my code. This way seems to work well if your API reflects what is in your model. While this may be easy, if things had to change on the back-end I could not easily hide it from the client (my front-end code). This creates a coupling that makes me squeamish.

A new way

RABL (Ruby API Builder Language) provides a way to use a templating system for generating JSON or XML in your view. RABL is a simple DSL that allows you to define your JSON responses in an easy, clean way. It is easy to setup with Rails 2.X, Rails 3, and Rails 3.X.

Using RABL the above becomes:

New rails controller with RABL

1 2 3 4 5 6 7 8
class RablController < ApplicationController
respond_to :json
def index
@students = Student.all
end
 
end

New RABL view file

1 2 3
object @students
 
attributes :firstname, :lastname, :email, :phonenum
view raw index.rabl This Gist brought to you by GitHub.

JSON Result

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
[
{
"student": {
"firstname": "Drew",
"lastname": "Clemens",
"email": "info@heysparkbox.com",
"phonenum": "937-401-9501"
}
},
{
"student": {
"firstname": "Andy",
"lastname": "Rossi",
"email": "info@heysparkbox.com",
"phonenum": "937-401-9501"
}
}
]
view raw rabl_json.js This Gist brought to you by GitHub.

At the end of the day I think that RABL provides a better way to define my APIs. Please note that my examples above are overly simple. This was done to show the ideas I am talking about. Please check out RABL for yourself to see if you think it's a better solution.

Other RABL resources

RABL on GitHub - https://github.com/nesquena/rabl

'If you’re using to_json, you’re doing it wrong' - http://engineering.gomiso.com/2011/05/16/if-youre-using-to_json-youre-doing-it-wrong/

Keep up with new posts in the Foundry by subscribing to our weekly email: The Spark.