opensoul.org

Sinatra serenades Rails 2

It turns out it’s really easy to mount a Sinatra application into your Rails 2 app (yes, there are still a few Rails 2 apps out there). Here’s how.

First, declare Sinatra as a gem dependency in config/environment.rb:

config.gem 'sinatra', :lib => 'sinatra/base'

Next, create a directory to put Sinatra apps in and add them to the Rails load path:

config.autoload_paths << Rails.root.join("app/sinatra")

Then, define a Sinatra app in a file in app/sinatra:

class TheJsonApi < Sinatra::Base
  before { content_type(:json) }

  get '/v2/foo' do
    {:foo => 'bar'}.to_json
  end
end

And finally, insert your Sinatra app as middleware:

config.after_initialize do
  config.middleware.insert_before("ActionController::Failsafe", "TheJsonApi")
end

Sinatra, being the classy framework that it is, is smart enough to act as a Rack middleware OR an endpoint (what’s the difference?). If you use it as a middleware, it will serve any routes that it knows about and pass on any that it doesn’t.

Why would you use Rails and Sinatra?

I’m working on large Rails application that consists mostly of an XML API. We’re working on a new version of the API with some significant changes. Since the new API will only have 7-10 endpoints, and only return JSON, we are thinking it will just be cleaner to build it as a Sinatra app. It will be easier to document and easier to maintain. And we are embedding it in the Rails app so it can make use of our existing models.

rails and sinatra December 10, 2010

3 Comments

  1. Martijn Storck Martijn Storck December 10, 2010

    This is cool, but wouldn’t it be easier to use Metal controllers for your API? I’ve compared results in Rails 3 and in there Metal is just as fast as mounting a Sinatra app. Plus it saves your co-developers from learning Sinatra.

  2. Brandon Keepers Brandon Keepers December 10, 2010

    Martin: Metal is an option too, but there’s a few reasons I’d rather use Sinatra.

    The first being that it is just much prettier (yes, I’m that shallow). All the routes and everything are self-contained. Releasing an updated API will be as easy as inheriting from the existing Sinatra app and overriding the routes that change (or, for significant revisions, copy the whole file and start modifying).

    But the second, and more influential reason, is that we had already started to rebuild the entire application (as a Sinatra app), but abandoned that effort after a few months in favor of just iterating on our existing application. So the new API is pretty much already build in Sinatra.

  3. Michael Guterl Michael Guterl December 23, 2010

    I really like this idea. Are you developing the Sinatra application independently from the Rails application or is it only developed in the context of the parent Rails app?

My name is Brandon Keepers. I like to build things, usually in Ruby or JavaScript. I work at GitHub and live in Holland, MI.

Popular Posts