Rails is a heavyweight framework and it does a lot of awesome stuff by default that only a few other frameworks provide. But most of the benefit goes right out the window when you’re using it to write a simple REST API. Lemme ‘splain.

What’s In a REST API?

When I say “your REST API”, I’m specifically talking about a little application server that serves requests over HTTP, preferably using REST principles, but not necessarily. Generally a REST API server is backed by a database or other form of data storage. It might provide calculation of some kind, either with a data store or not. You can think of the Twitter API or the GitHub API, for instance, or simpler things like querying data points from your metrics backend.

What I am not talking about is anything serving a user-visible HTML-CSS-and-JS web site, meant to be consumed by a user, interactively, in a browser. Let’s call that a “web app server” instead of a “REST API server”.

Rails should be used for web apps in most cases, and REST APIs only rarely.

Why Not?

Rails is heavy. Installing Rails on a fresh system requires installing the following gems, at minimum:

Successfully installed i18n-0.6.1
Successfully installed multi_json-1.5.0
Successfully installed activesupport-3.2.9
Successfully installed builder-3.0.4
Successfully installed activemodel-3.2.9
Successfully installed rack-1.4.1
Successfully installed rack-cache-1.2
Successfully installed rack-test-0.6.2
Successfully installed journey-1.0.4
Successfully installed hike-1.2.1
Successfully installed tilt-1.3.3
Successfully installed sprockets-2.2.2
Successfully installed erubis-2.7.0
Successfully installed actionpack-3.2.9
Successfully installed arel-3.0.2
Successfully installed tzinfo-0.3.35
Successfully installed activerecord-3.2.9
Successfully installed activeresource-3.2.9
Successfully installed mime-types-1.19
Successfully installed polyglot-0.3.3
Successfully installed treetop-1.4.12
Successfully installed mail-2.4.4
Successfully installed actionmailer-3.2.9
Successfully installed rack-ssl-1.3.2
Successfully installed thor-0.16.0
Successfully installed json-1.7.6
Successfully installed rdoc-3.12
Successfully installed railties-3.2.9
Successfully installed rails-3.2.9
29 gems installed

(Plus Bundler and Rake, not shown)

And it’s not just the 31 gems. A fresh clean Rails app (“rails new myapp”) has 37 directories, takes 164kb, has 18 .rb files, hard-codes how to do things for three different app environments and has a frightening amount of configuration.

It’s hard to specifically measure how many API entry points Rails has (do all those automatic ActiveRecord accessors count? Does the controller/view interface count?), but at least several hundred methods.

Rails is wonderful, but it’s heavy. It requires a lot of code, a lot of structure in your application, and a lot of mental overhead to keep track of. How long did it take you to learn Rails? How much of it do you know? And how big is “The Rails 3 Way”?

The Alternatives

Here’s another way to judge whether Rails is a high-overhead choice for a REST API. Compare it to Sinatra, where a small API app is one file, and often under 30 lines. Or Padrino, which includes the same things but also has database migrations, and it’s still tiny. Or stripped-down specific API choices like Grape. Even RocketPants – it’s also built on the ActiveFoo Rails-y libraries… But it doesn’t use Rails because putting together a full Rails app is simply too heavyweight.

The Rails-API project exists (and is run by Rails core members!) specifically because vanilla Rails is seen by Rails core members as not being a reasonable choice for APIs. Think about that.

But It Doesn’t Get In My Way!

The amount of overhead we’re talking about looks small if you’re Twitter-sized. So why does Twitter use Java instead?

Because Rails overhead doesn’t just stop after “rails new” finishes running.

Trying to do even plain-vanilla object-oriented programming in Rails is suddenly a complicated topic with a lot of people weighing in, sometimes at book length. You have to educate every new programmer on your project in that several-hundred-entry-point Rails API and how you mix it with OO.

Fundamentally, a dedicated API framework like Grape or Sinatra is just lower overhead to get new people up to speed.

Or, eventually, a company gets big enough to care a lot about per-machine performance and switches to a faster language, as Twitter did with Java. Let’s assume your API server isn’t as big as Twitter’s yet.

Why You Knocking My Homie Rails?

I love Rails, really and truly. I wrote a whole book singing its praises. No kidding. I believe that a small team putting together a user-facing web site should use Rails because no other framework comes remotely close. Rails is versatile, powerful, flexible and lets you change direction on a dime.

And for that team’s API server, when they have a separate one, that team should use Sinatra. Or Grape. Or even just plain Rack.

Also, if they build their framework in Rack directly, they should buy my book because the basic Rack docs aren’t great – it’s better to walk through building a full framework if you want to understand it.