18 Jun
Rack is a modular web server interface for Ruby. Instead of coding your application for a particular server interface like CGI or Ruby’s WEBrick, you adapt your application instead to the Rack interface specification, and invoke the appropriate server handler. With just a minuscule amount of work, you can easily deploy your app using any of WEBrick, Mongrel, FCGI or CGI.
You can install Rack as a Ruby gem:
gem install rack --include-dependencies
To get started with Rack, the entry point for your application must be an object that responds to a call method and takes a single parameter: a hash of environment variables. Your call method must return an array containing the HTTP response code, a set of headers including the content type, and finally the response body.
This code probably explains it best:
# hello_world.rb
require 'rubygems'
require 'rack'
class HelloWorld
def call(env)
[ 200, # HTTP Response Code
{ "Content-Type"=>"text/plain" }, # HTTP Headers
[ "Hello, World!" ] # Body
]
end
end
# Instantiate your app
hello_world_app = HelloWorld.new
# Deploy using WEBrick handler
Rack::Handler::WEBrick.run hello_world_app, :Port => 3000
You then start your web application simply by calling it:
# ruby hello_world.rb
[2007-06-17 20:42:31] INFO WEBrick 1.3.1
[2007-06-17 20:42:31] ruby 1.8.5 (2006-08-25) [i386-mswin32]
[2007-06-17 20:42:31] INFO WEBrick::HTTPServer#start: pid=5894 port: 3000
Since most of us don’t want to deal with the raw request and response bodies ourselves, Rack supplies easy-to-use Request and Response classes. Here’s an example app that takes a single GET param:
...
class HelloWorld
def call(env)
req = Rack::Request.new(env)
name = req.GET['name'] # post: req.POST['name']
# Default content-type is text/html
# Default status is 200
Rack::Response.new.finish do |res|
res.write "Hello, #{name}!"
end
end
end
# This time, deploy using plain-old CGI through Apache/Lighttpd/etc.
hello_world_app = HelloWorld.new
Rack::Handler::CGI.run hello_world_app
Along these lines, Rack also has helpers for URL routing, cookie handling, and more.
For fun, I’ve taken this simple CGI contact form written in Ruby from my first Stepping off the Rails article and converted it to Rack. It can now be deployed using any of the handlers mentioned above, or still as plain CGI. Talk about flexibility.