Rabl is a powerful tool for building a Rails JSON API. It allows you to easily return JSON responses from your APIs in a clear and concise way. And separate the logic of your API from the presentation of the data. 

With that said, the Rabl syntax can be hard to configure initially:

A missing comma or symbol in one file can lead the whole serializer to crash, leaving you with confusing error messages.

This article will help you get set up with Rabl and will cover the following three points:

  • Why you should use Rabl
  • How to get Rabl set up
  • The basics of how to use it

If you’d like to read more about how to send requests to your Rabl API, or if you’re looking for more advanced Rabl techniques, read our follow-up articles that dive deeper into each of these topics.

Why Use Rabl

There are several reasons why you might use Rabl over a traditional Rails view:

  1. Separation of concerns: Rabl allows you to separate the logic of your API from the presentation of the data. At NextLink Labs, we find it extremely helpful as a bridge between Rails and React. We love having the back-end elegance of our Ruby APIs feeding their data into our highly-interactive, Reactive front-ends.
  2. Flexibility: Rabl provides flexibility when it comes to formatting your API's response. In addition to the JSON responses already mentioned, Rabl also supports XML and other formats. So you should find it compatible with most popular front-end frameworks. You can even create custom formats by creating custom templates.
  3. Nested and complex data structures: Rabl allows you to easily include related models and nested data structures in your API's response.
  4. Customizable: With Rabl, you can use conditionals, loops, and Rails helpers to customize the way your data is presented to the client.
  5. Efficient: Rabl is optimized for performance. It's a lightweight and efficient tool that can help you build fast and responsive APIs.

Now, let’s get into the Rails API tutorial.

How To Get Started with Rabl

The initial setup for Rabl is similar to most Ruby gems: 

Add the library (along with the related gem oj) to your Gemfile and run bundle install. 

Note: Full Rabl setup instructions can be found here.

# Gemfile

gem 'rabl'
gem 'oj

bundle install

Step 1: Set Up Your Basic User Model

Our structure typically involves a call from our front end to one of the API endpoints.  

So, if you’re comfortable with Rails routes and controllers, there’s good news: You still get to write the route, the model, and the controller in exactly the way that you’re used to.

First, create a model for your users:

rails g model User first_name:string last_name:string
rails db:migrate

Add routes for the user:

config/routes.rb

resources :users, only: [:show, :index]

Create a users_controller.rb file in app/controllers:

app/controllers/users_controller.rb

def show
      @users = User.all
end

def show
      @user = User.find(params[:id])
end

You can’t fetch any JSON data from your API if your database is empty. In your Rails console, create at least one user.

User.create(first_name: "Test", last_name: "User")

Step 2: Configure Your Rails API Serializer

With that foundation set up, we’ll begin configuring our Rabl files.

The Rabl file lives in the same place where you would normally locate a Ruby view file: In the views directory of your app folder. After all, that’s where Rails will look to next after going through the controller.  

# app/views/users/show.rabl

child @user => :result do
   extends 'users/_user'
end

 

Two things to notice here: 

First, the file is named with the controller action that will call it, “show.”  

Second, this file uses a .rabl extension, rather than .html.erb. This signals to the Rabl gem to wake up and do its work.

There are two lines to include in this file: 

The “object” line tells Rabl to use the @user variable as the source of data for the template. (This is the instance variable that we created in the controller.)  

The “attributes” line specifies which user attributes should be included in the JSON representation of the user. In this example, we’ve included the first name and last name. If you wished, you could also include the :id. Similar to the show file, here is an example of an index endpoint that will list data for all users:

# app/views/users/index.rabl

node(:total_records) do
  User.all.count
end

child @users => :result do
  extends 'users/_user'
end

And the final piece is to add the partial with the actual attributes for the user record itself. With our user model this can be as simple as the following:

# app/views/users/_user.rabl

attributes :id, :first_name, :last_name

Now you’ve got your Rails API serializer files.  The next step is…

Nothing.

That’s it. You now have a functional API endpoint!

But don’t take our word for it. You can test the endpoint using a tool like Postman or Curl to send a GET request. Or you can visit the endpoint in your browser. If you haven’t yet started your Rails server, you’ll need to do that.

rails s

 

And then, assuming that your Rails app is running on Port 3000, you’ll visit this url in your browser window:

http://localhost:3000/users/1

You should see your user object’s JSON response:

 




Step 3: Set Up Your Rabl Initializer

To fully control how your API endpoints send data, you will need to customize the Rabl initializer. 

Many of the configurations here come down to your team’s preferences But we recommend keeping your Rabl initializer relatively simple with just the following lines:

# config/intializers/rabl_init.rb

require "rabl"

Rabl.configure do |config|
  config.include_json_root = false
  config.include_child_root = false
  config.view_paths = ["app/views/"]
end


Step 3: Conclusion

Now that you can receive useful JSON responses to your API requests, you’re free to organize that data in your front-end framework of choice. 

In the next article, we’ll detail how NextLink Labs uses axios in our React front-ends to fetch this data.

If your team is struggling with technical debt as you build your custom software applications, we’re happy to provide additional guidance!