Ionrock Dot Org

by Eric Larson

My Weblog

A Quick Javascript Server Side Framework

Recently, I've been thinking a lot about Javascript on the server. Last night I took a minute to see what a simple framework might look like. After going through the different frameworks available, it was clear there were a wide array of reasons people created server side Javascript. Very few are thinking in terms of traditional web frameworks at this point, so the available options are slim and rather high level. Fortunately, I found Jack, the WSGI/Rack clone for server side Javascript. After reading up a bit, I figured I'd see how fast I could put together a simple framework for writing basic apps. Here is what I came up with:

var Jack = require("jack"); var http_status = function (code, msg, body) {     var template = {         head : '<html><head><title>{MSG}</title><head>',         body : '<body><h3>{BODY}</h3></body></html>'     };     var redirects = {         300 : 'MultipleChoices',         301 : 'Moved Permanently',         302 : 'Found',         303 : 'See Other',         304 : 'Not Modified',         305 : 'Use Proxy',         // 306 : 'Unused (not implemented, obviously)',         307 : 'Temporary Redirect'     };     var messages = {         400 : 'Bad Request',         401 : 'Unauthorized',         402 : 'Payment Required',         403 : 'Forbidden',         404 : 'Not Found',         405 : 'Method Not Allowed',         406 : 'Not Acceptable',         407 : 'Proxy Authentication Required',         408 : 'Request Timeout',         409 : 'Confict',         410 : 'Gone',         411 : 'Length Required',         412 : 'Precondition Failed',         413 : 'Request Entity Too Large',         414 : 'Request URI Too Long',         415 : 'Unsupported Media Type',         416 : 'Request Range Not Satisfiable',         417 : 'Expectation Failed',         500 : 'Internal Server Error',         501 : 'Not Implemented',         502 : 'Bad Gateway',         503 : 'Service Unavailable',         504 : 'Gateway Timeout',         505 : 'Version Not Supported'     };     var res = new Jack.Response();     if (redirects[code]) {         res.redirect(msg, code);         return res;     }     var msg = msg ? msg : messages[code];     msg = msg ? msg : code;     body = body ? body : msg;     res.status = code;     res.write(template.head.replace('{MSG}', msg));     res.write(template.body.replace('{BODY}', body));     return res.finish(); }; var pp = function (o) {     for (k in o) {         print (k.toString() + ': ' + o[k]);     } }; var app = function (routes) {     return function (env) {         var req = new Jack.Request(env);         var meth = req.requestMethod();         var path_info = req.pathInfo();         for each(route in routes) {             var m = path_info.match(route.regex);             if ( m ) {                 if (route.methods[meth]) {                     env['app.matches'] = [p for each(p in m.slice(1)) if (p)];                     return route.methods[meth](env);                 }                 return http_status(405);             }         }         return http_status(404);     }; }; var route = function (regex, methods) {     return {         regex : regex,         methods : methods     }; }; exports.app = app([     route(/^\/(\d+)\/(\w+)(\/)?$/, {         GET: function (env) {             var url = env['app.matches'];             var res = new Jack.Response();             res.write('The id is ' + url[0] + ' and the name is ' + url[1]);             return res.finish();         }     }),     route(/\//, {         GET: function (env) {             var res = new Jack.Response();             res.write('hello world!');             return res.finish();         }     }) ]);

There is no templating or anything, but having the basic means of setting up some handlers based on the request URL and method seems like a good start. Hopefully someone else might find it interesting and/or helpful.

Posted Wed Jul 8 17:01:18 2009 by Eric Larson
Created using Python, jQuery and Emacs