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