Updated: FreshBooks.rb

FreshBooks happened to re-release their API today. It’s a pretty significant overhaul, and I’ve re-written my Ruby wrapper to reflect the changes. The code is still in it’s early stages, but if you want to check it out, you can pull it from my Subversion server:

svn co svn://benlog.org/pub/freshbooks

It’s also got a new name: FreshBooks.rb. The old name (FreshBooks API for Ruby) was a little long winded.

Update: Fixed up a few bugs pointed out by Flinn. Thanks for the heads up.

Stepping off the Rails with Rack, the modular web server interface for Ruby

What’s Rack?

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

Simple Example

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

Even Simpler

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.

Contact Form Example

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.

Article: Staying on top of web development trends

Technology moves fast – on the web, even faster. If you’re a developer, how do you stay on top of new techniques, tools, and languages? Below I’ve shared some resources that help me stay current.

You can check out the article over at Fresh Thinking.