John Goodall

Research Scientist / Team Lead

Situation Awareness and Visual Analytics team

Oak Ridge National Laboratory

  865-446-0611

  jgoodall@ornl.gov

 

Tako web framework

There are a bunch of node.js web frameworks. They provide support for routing, templating, and Express is probably the most common and mature. It uses Connect for its middleware component. It is pretty awesome, with lots of middleware available (try npm search connect- and npm search express-). It has been around for a while, is probably the most heavily used, and is under current development. It is flexible in terms of the template engines that you use, but using jade, which makes writing html not suck nearly as much as usual, is installed by default. (There is also another library, consolidate, from the same ridiculously prolific developer of express and jade for hooking into a whole bunch of other template engines in express.)

There are other frameworks out there too:

  • Geddy is a monolithic solution from the folks at yammer.

  • Flatiron, from the awesome folks at nodejitsu, is a bunch of small libraries that can be composed to make web or CLI apps. Pretty cool that you can use the same components to build both web and CLI apps. I’ve used their logger, winston, before and it just works.

  • Restify is a libray with a similar feel to express for building RESTful APIs.

  • ApiServer is a another library for building an API server.

A recent nodeup podcast covered some of these. Frankly, I dont have time to try them all, and dont have any real complaints with express. All the same, I decided to give tako a few hours and see what it was all about.

Tako

Mikeal Rogers, @mikeal, and Max Ogden, @maxogden, recently released a bunch of open source libraries for node. One of these projects is a web framework, called tako. It is really small, a single 24k file (compared to express, which looks like it is ~96k based on the files in lib). It is simple by design. From the author:

tako includes all the features we needed from a web framework to build our app. It’s not a middleware or plugin system and doesn’t include one. It’s a tool for handling HTTP requests in a sensible way.

It has a composable API around routes. A route is an object and based on what kinds of handlers you add and conditions you might set tako can respond properly to various HTTP methods and content-type requests in an appropriate manner.

It can also serve files sensibly using filed which already streams and returns/responds to proper etag and if-modified headers.

It already includes socket.io. It includes JSON support. It can serve buffers from cache.

The first thing you notice is that there is not a lot of documentation, basically just a minimal readme. The next thing is that it is pretty straightforward to get started. Here is a simple example for a single page app:

    var fs = require('fs')
      , path = require('path')
      , tako = require('tako')
      , gzip = require('tako-gzip')

    // global variables
    var app = tako()
      , indexHtml = fs.readFileSync(path.join(__dirname, './html/index.html')).toString()
      , notfoundHtml = fs.readFileSync(path.join(__dirname, './html/notfound.html')).toString()

    // static files
    app.route('/public/*').files(path.join(__dirname, './public'))

    // routes
    app.route('/')
      .html(renderIndex)
      .methods('GET')

    // page not found
    app.notfound(notfoundHtml)

    // listen
    app.httpServer.listen(8000)

    // just render the html
    function renderIndex(req, res) {
      res.end(indexHtml)
    }

All it does is serve an index file and the static assets. I am using grunt to compile jade templates into html, combine and uglify javascript files, and combine and minify css files. So the web server is only serving static files. There is also an html file for 404 errors.

Socket.io

Tako includes socket.io. To use it:

    app.sockets.on('connection', function (socket) {
      socket.on('connect', function () {
        app.sockets.emit('user connected') // broadcast
      })
      socket.on('disconnect', function () {
        app.sockets.emit('user disconnected') // broadcast
      })
    })

One thing that took me a few minutes to figure out is how to get to the socket.io settings. I think there are two ways:

  1. when you instantiate tako: app = tako({'socketio':{'log level':2}})
  2. using socket.io Manager: app.socketioManager.set('log level', 2)

Obviously, you can do more than change the log level, see more configuration options.

Plugins?

Tako does not support plugins. But there seems to be some plugins.

    npm search tako-
    NAME                DESCRIPTION                   AUTHOR   DATE              KEY
    tako-cookies        A cookie middleware for tako  =isaacs  2012-04-20 19:23
    tako-gzip           gzip for tako                 =kesla   2012-04-29 22:17
    tako-session-token  session tokens for tako       =isaacs  2012-04-20 19:47

Author isaacs wrote npm and modules like supervisor and inherited ‘dictatorship’ of node itself from Ryah Dhal, node’s creator. I dont know why he is he using tako, but that is a good sign right?

So back to plugins, the gzip one is pretty straightforward:

    var gzip = require('tako-gzip')
    app.on('request', gzip)

Not sure why you wouldn’t want to do that…

If you listen to the [Nodeup podcast]((http://nodeup.com/) or read the author’s writings, you know he is a crazy smart, thoughtful, and opinionated developer. I want to use this framework, but I am not a good enough node.js developer to be able to figure out everything it is doing. So I think it is a nice framework, but needs a lot of help getting the same level of documentation as other, more mature projects like express. If I need to put together something quick and relatively straightforward, then I love this, but for larger projects, I am sticking with Express until the documentation for this one gets a bit better. My hunch is that I am not the target audience and this is made for people that are going to dig into the source code and figure out exactly how it is working, but then again, if you are going to do that, then do you really need a web framework?