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