2

Forget About Little Old CGI

Posted in Ruby off Rails at March 17th, 2008 / 2 Comments »

Maybe someone may have told you to use ruby and CGI together, but I think that person has a screw loose. I mean, come on. Everyone knows that what you really need to use is Rack

Why Rack

Well for one, it’s light weight. So if you want to deploy your ruby script using CGI, you can do that with Rack.

But let’s say, you want to your script to Mongrel, or WEBRick, or FCGI; you can do that too, and with very few changes to your script. That’s because Rack abstracts all the boilerplate code you would need to work with those servers and bundles it up into a nice interface for you to use.

Oh, and the code to use Rack is very easy. Here’s an example of a Rack app for you:

Examples

%w(rubygems rack haml).each { |dep| require dep }

class IndexPage
  def call(env)
    haml_engine = Haml::Engine.new(File.read('../templates/index.haml'))
    [
      200,
      { "Content-Type" => "text/html" },
      haml_engine.render(Object.new, {})
    ]
  end
end

Rack::Handler::CGI.run(IndexPage.new)

The secret behind Rack is that it will run any ruby object that has a call method and pass in the environment variables to it. In that environment variable, you will find things like HTTP_HOST, or QUERY_STRING, and the like.

If you wanted to have this script now work with WEBRick, no problem.

# Same code as above, with just a little tweak to the last line

Rack::Handler::WEBRick.run(IndexPage.new, :Port => 3000)

Tada! So now you can run a test server without worrying about setting up Apache or Lighttpd.

More Goodness

To make your life easier, Rack also comes with a set of middleware for you to use. Say you have an error in your application. Perhaps you would like to see that error formatted nicely in your browser. You can enable Rack::ShowExceptions. Perhaps you would like the code you have to be reloaded from the server whenever it changes, like when you’re developing your application, then you can use Rack::Reloader.

To use those options, you can write your Rack handler like

app = Rack::Builder.new do
  use Rack::CommonLogger  # apache-like logger
  use Rack::ShowExceptions
  use Rack::Reloader
  use Rack::ShowStatus  # create default pages for common HTTP error codes
  use Rack::Lint  #ensures all applications behave validly
  run Index.new
end
Rack::Handler::WEBRick.run(app, :Port => 3000)

There’s plenty of magic going on with Rack; A magic that does not sacrifice speed and/or flexibility. I would highly recommend giving Rack a look into the next time you want to write a simple web page.

Published in Ruby off Rails
Tags: , ,

2 Responses to “Forget About Little Old CGI”

  1. September 10th, 2008 at 2:26 am #ts

    hi, i wonder how Rack::Reloader works? My simple code below:

    ================================================
    %w{rubygems rack thin}.each {|dep| require dep}

    class HelloWorld
    def call(env)
    [200,{"Content-Type" => "text/html"},"hello world!!"]
    end
    end

    app = Rack::Builder.new do
    use Rack::CommonLogger
    use Rack::ShowExceptions
    use Rack::Reloader
    use Rack::ShowStatus
    use Rack::Lint
    run HelloWorld.new
    end

    Rack::Handler::Thin.run(app, :Port => 3000)

    ============================================

    if i change the “hello world!!!” string to something else. A refresh on the web browser doesnt works. I wonder am i missing something?

  2. September 16th, 2008 at 8:00 pm #K. Adam Christensen

    Hi,

    well, from what I can gather, there are two reasons that this isn’t working for you.

    1. For the Reloader to work, you need to have the code that needs to be reloaded to be in a separate file. So just move HelloWorld to hello_world.rb

    2. At the end of Rack::Builder.new, add the to_app() method.

    app = Rack::Builder.new do
    use Rack::CommonLogger
    use Rack::ShowExceptions
    use Rack::Reloader
    use Rack::ShowStatus
    use Rack::Lint
    run HelloWorld.new
    end.to_app

    I discovered this through the “mailing list”:http://groups.google.com/group/rack-devel/browse_thread/thread/11681e8ce6b58cac

Leave a Reply