Wednesday, January 28th, 2009

Jack: A port of Rack to JavaScript

Category: JavaScript, Server

<p>Tom Robinson (Cappuccino, Objective J, 280* fame) is someone you should follow on Github as he comes up with cool stuff such as cappruby “a Ruby implementation on top of JavaScript / Objective-J runtime. Proof of concept stage.”

But that isn’t why we are here today. Tom has a new project called Jack which is a port of the Ruby Rack project to JavaScript:

echo “Rack provides an minimal interface between webservers supporting Ruby and Ruby frameworks” | sed -e
s/Rack/Jack/g -e s/Ruby/JavaScript/g

Indeed, Jack is a fairly straightforward port of Rack (http://rack.rubyforge.org/) to JavaScript, with adjustments where necessary. Of course it is meant for use on the server rather than in the browser.

It provides a common interface between web servers and web applications or frameworks written in JavaScript.

Jack currently supports the Jetty (and other servlet containers) and Simple webservers using Rhino, and it should be easy to integrate with other JavaScript interpreters and web servers.

Writing Jack Applications

A Rack application is simply a JavaScript object that responds to the “invoke” method. It should return an array
containing three elements: the status code (an integer), the headers values (a hash), and a body object (anything that
responds to the “each” method).

We have extended JavaScript Function objects to respond to “invoke” (it just calls itself, so any function is a valid
Rack application, provided it returns the right types), and JavaScript Array and String objects to respond to “each”
(so they are valid “body” responses), thus the following is a valid Jack application:

javascript
< view plain text >
  1. function(env) {
  2.   return [200, {"Content-Type":"text/plain"}, "Hello world!"];
  3. }

Writing Jack Middleware

Jack middleware performs some sort of pre or post processing on requests, such as logging, authentication, etc. Most
Jack middleware, by convention (and required for use with the Builder DSL, etc), is a constructor that takes in one
argument, “app” (which will be a Jack application) and creates a Jack application (i.e. something that responds to
“invoke”). In it’s “invoke” method it will typically optionally do some preprocessing, followed by calling the “app”
that was provided in the constructor, optionally followed by some post processing.

For example, the “Head” middleware call the “app”, then checks to see if the request HTTP method was “HEAD”. If so, it
clears the body of response before returning it, since HEAD requests shouldn’t have a response body.

A more complicated middleware might need to peform postprocessing on the body contents. A common pattern is to call
the app, then store the body as a property of itself and return itself *as* the body instead. It also defines an
“each” method on itself that proxies to the stored body property. A good example of this is the CommonLogger
middleware, which does this in order to calculate the body length for logging.

Love to see this. I think that it could be time for SSJS folks to start making APIs!

(via Kevin Dangoor, team mate at Mozilla Dev Tools Lab)

Related Content:

  • Cooling racks
    Expert Robert McFarlane tells readers what he thinks about cooling...
  • Jack Madden
    Jack Madden writes about everything related to enterprise mobility management at...
  • "Ports"
    SearchNetworking ANZ scours the net for news and opinion on...
  • "Guest" router jacks
    +++--
    3.6 rating from 17 votes

1 Comment »

Comments feed TrackBack URI

Rack seems to be getting traction as a base for prototyping new hosting ideas and models. If Jack can do the same that is great. We’ll be looking at it for http://www.ejscript.org and for the Appweb embedded web server http://www.appwebserver.org

Comment by mob590 — February 9, 2009

Leave a comment

You must be logged in to post a comment.