Jade Templates Introspection

The Jade Template Engine for Node now have the ability to manipulate themselves based on the parse tree constructed from a nested block. This has extreme potential, in that developers can now alter jade templates dynamically, constructing their own syntactic sugar.

One of my favorite (but not only) use-cases for this functionality, would be that of a database record edit form. Typically your template may be littered with helper functions such as input(‘text’, user.name) or similar. With the ability for filters to now accept a block of tags, we can apply the Visitor pattern in order to convert tags to other tags, alter existing tags or manipulate Jade in almost any way without writing an entirely new compiler.

So how is something like an edit form typically handled? With rails / ERB it might look something like this, which although is “fine” it is generally in my opinion difficult to read, and clearly mixes code with the template.

Although Jade provides an arguably cleaner syntax, it does still essentially have the same issue of constantly mixing verbose logic within the template itself to do common things like display errors on a field as shown below.

With Jade’s new reflection capabilities we could vastly simplify these patterns by creating a :model filter and manipulating the parse tree. Below we lay out how we would prefer to handle model forms, we could take this even further and check model property types to attempt creation of the appropriate field types automagically, but for simplicity we will not.

Everything you see below is valid jade, however we utilize attributes to simulate argument passing, which is fantastic because we could easily transparently support input error handling without the use of our custom field tag.

The output we will achieve after our parse tree manipulation will be:

And here is our filter / Visitor implementation. Although the DOM-like node api is verbose, this extra layer adds endless flexibility to Jade, and while you are at it, why not generate the elements constructed below with Jade as well ;) using Jade’s new jade.parse(str) method.

Keep in mind that all of this is performed at the compilation level, typically which is only called once per template, so essentially no overhead over the lifetime of an application. That is it for now, make sure not to abuse this functionality :p.

happy Jade-ing?

nDistro Screencast - NodeJS Deployments In Seconds

I decided to take some time and go screencast-happy today, the first screencast is an introduction to my nDistro nodejs distribution toolkit. nDistro allows you to create node deployments in a matter of seconds.

Ps. Dont mind my annoying bird! here is the screencast

Getting Started With Express

In this short tutorial for Node Knockout we will be creating a small application using the popular Express framework.

Express is a light-weight Sinatra-inspired web development framework. Express provides several great features such as an intuitive view system, robust routing, an executable for generating applications and much more.

Installation

To get started with Express we first have to install it. There are several ways to do so, however my personal favourite is the following command which does not require a node package management system:

$ curl http://expressjs.com/install.sh | sh

Alternatively if we have npm installed we can simply execute:

$ npm install express

First Express Application

To create our first application we could use express(1) to generate an app for us, however an Express app can be a single JavaScript file if we wish, and in our case of a simple “Hello World” app that is exactly what we will do.

The first thing we need to do is require express, and create an app. The app variable shown below is an express.Server, however by convention we typically refer to Express servers as “apps”.

var express = require('express'),
    app = express.createServer();

Our next task is to set up one or more routes. A route consists of a path (string or regexp), callback function, and HTTP method. Our hello world example calls app.get() which represents the HTTP GET method, with the path “/”, representing our “root” page, followed by the callback function.

app.get('/', function(req, res){
    res.send('Hello World');
});

Next we need our server to listen on a given port. Below we call listen() which attempts to bind the server to port 3000 by default, however this can be whatever you like, for example listen(80).

app.listen();
console.log('Express server started on port %s', app.address().port);

We can execute the app simply by executing node(1) against our JavaScript file:

$ node app.js
Express server started on port 3000

Finally to confirm everything is working as expected:

$ curl http://localhost:3000
Hello World

Middleware

Behind the scenes the Connect middleware framework developed by myself (TJ Holowaychuk) and Tim Caswell is utilized to power the Express middleware. For example if we wish to add logging support to our hello world application, we can add the following line below app = express.createServer();:

app.use(express.logger());

For more information on middleware usage view the Middleware section of the Express Guide.

Source

Below is all 12 lines of source we used to create our first Express application:

var express = require('express'),
    app = express.createServer();

app.use(express.logger());

app.get('/', function(req, res){
    res.send('Hello World');
});

app.listen();
console.log('Express server started on port %s', app.address().port);

Connect vs JSGI

Last week Kris Zyp posted JSGI vs Connect, claiming that Connect is slower than JSGI.

Another claim is that JSGI is far more intuitive, which I consider false. First of all the library does not follow common nodejs idioms, and the configuration also causes the “boomerang effect”, although in the end only the community will decide what they want.

Krisbenchmarks generally consisted of testing the Connect middleware loop which invokeshandle()` on each of the layers. Even with the typical “Hello World” benchmark these claims can be quickly disproven, since a simple for loop measures in the microseconds, and has no effect in comparison to ANY real-world application routine.

Comparing Connect / JSGI / Node

The following gist contains the test files used. As you can see Connect middleware can easily be used stand-alone and in my opinion feels more natural to implement, where as the JSGI middle is comparably awkward.

Below are the results of ab -n 8000 -c 50 -k http://dev:8080/ per each server. Funny enough, JSGI actually placed last in the “Hello World” game:

connect: 8859 rps
jsgi: 8357 rps
node: 9184 rps

OMG JSGI IS SO SLOW.. well no, it is just fine, but so is Connect. We are talking about milliseconds here! ANY call to the database ANY “real” operation will be far more expensive.

Response Curve

In my Connect Introduction article the following graph illustrates that Connect has nearly no overhead, as the response curve is almost identical to that of a plain node server.

Hello World

Closing Thoughts

The truth is, be it Connect, JSGI, fab, or plain old node, none of these will have a profound effect on performance, and can certainly not be considered a bottleneck.

Use what you like! Connect is backed by the all mighty Ext JS team, is licensed MIT until the end of time, and is in development by several node rockstars, it will adapt as the community sees fit, but is already gaining speed.

Happy nodeing!

Connect - Middleware For NodeJS

Yesterday myself and Tim Caswell open-sourced the first Ext JS nodejs project, Connect. Connect is an abstraction layer, providing node developers with an effective, high performance solution for rapid development using interchangable components called “middleware”.

Middleware

Middleware provides node developers with simple “plug and play” modules, which may be stacked in any order desired, aiding in rapid development. Connect middlware are regular node modules exporting the handle() method, however conceptually they fall into two categories, filters, and providers.

A “filter” conceptually sits arbitrarily within the middlware stack, processing incoming and outgoing traffic, but typically does not respond to a request. An example of this is the log filter provided by Connect, it does not respond to any request, it simply proxies function calls in order to log request data.

A “provider” differs conceptually in the fact that it provides an end-point in the stack. However this may not always be the case. For example a json-rpc provider may choose not to process or respond to a request if the Content-Type header is not application/json. A classical example of a provider is the static provider which serves static files.

Executable

Connect is a dual purpose library, rapid development is not the only goal in mind. Also provided is the connect executable which can be used to daemonize Connect servers (and regular node servers) using an extremely simple command-line interface.

For more information on the connect executable install Connect and run:

$ man connect

Performance

Performance is a top priority for Connect, and we have the benchmarks to prove it. The following benchmarks were performed with ApacheBench, node 0.1.97, thin 1.2.7, sinatra 1.0, and rack 1.1.0.

The benchmarks bundled with Connect consistently showed that the library has nearly no overhead compared to a regular node server when responding with the typical “Hello World” response.

Hello World

Next up we have node, sinatra (thin), and Connect serving jquery.js, a roughly ~57kb.

Static jQuery

If you wish to run the benchmarks on your own machine, first execute:

$ make benchmark

Then generate the graphs with gnuplot:

$ make graphs

Once complete:

$ open results/graphs

Conclusion

Connect is awesome, what are you waiting for! head over to the Github repo and fork away.