Fast JSON API Controllers in Rails

by Logan Leger on

We have a Rails app that essentially acts as an API for an iOS app. It provides JSON endpoints to pull some resources. The iOS app only reads data, so the only verb used is GET. There are dedicated controllers just for the API actions — the admin backend is handled through separate controllers.

I was making some updates to admin backend yesterday and I noticed that the API controllers needed some attention. They were standard controllers, so they were inheriting from ActionController::Base, which includes a lot of stuff we just didn’t need. I ran a quick test with Apache benchmark and the median response time over 1,000 requests was roughly 630ms. Wow! I can do better than that.

Since Rails 3.0, we’ve had the ability to instead inherit from ActionController::Metal. It’s bare metal, if you will, and includes the basics. You have to add in the modules you need on top, so you really get to fine tune what the controller does. I had to dig around in the Rails source and figure out the modules I needed, but in the end we saw an amazing 50% performance increase — the media response was down to just 325ms. It’s really noticeable on the iOS side, too.

Here’s an example controller:

    class ArticlesController < ActionController::Metal
        include ActionController::Rendering
        include ActionController::Renderers::All  
        include ActionController::MimeResponds
        include ActionController::ImplicitRender
        
        respond_to :json
        
        def index
            @articles = Article.order("published desc").limit(25)
            respond_with(@articles)
        end

        def show
            @article = Article.find(params[:id])
            respond_with(@article)
        end
    end