Express 3.x alpha reference docs

Since I don’t have the Express 3.x site up yet I thought I would whip up a quick set of markdown docs from the source comments using dox.

To view these markdown docs in your terminal install mad(1):

$ cd /tmp && git clone --depth 1 git@github.com:visionmedia/mad.git && cd mad && make install

Update your mad-pages:

$ mad --update

Profit!

$ mad express

HINT: Press “/”, type and press enter to search. The keys u and n move to the prev / next occurrences:

HINT HINT: There are also mad(1) pages for Jade, HTTP status codes, errnos and others.

Express 3.0.0 alpha1

I just released the first alpha, but beware! the documentation has not been updated. I wanted to defer a release until I had time to re-write the site, but meanwhile people have been using the master branch anyway, so we might as well make it official (and available via npm).

The alpha is by no means complete, some features still need adjusting, though mainly internal refactoring. The wiki contains both the 2.x to 3.x migration guide, and documentation for most of the new features added. It’s worth noting you’ll also gain new features from Connect 2.x as well, which Express 3.x depends on.

There are quite a few new http utilities, better reverse proxy support, and refinements to the view system. Express 3.x is even smaller than 2.x totalling 975 SLOC according to sloc(1), where Express 2.x was around 1300. Most of the effort goes into actually removing and refining code to increase quality, and lots of test coverage (4286 SLOC).

I’ve also started a Express 4.x Roadmap with some details on where things may go in the future.

Contributing

If you’d like to contribute, one of the best ways right now would be to help upgrade the ./examples ! The Express repo has many examples, roughly half of which still use 2.x code and may not work. This time around we have test coverage for these examples, but many still need to be upgraded. To contribute first install the development dependencies:

$ npm install

Then run the acceptance tests:

$ make test-acceptance

Add some tests for an example, write some tests, make sure they work, then open a pull-request :)

That’s all for now! When I have time I’ll be rewriting the site, updating the wiki, and of course finishing the release. If there’s anything you find yourself doing often and think has a home in core let me know!

cheers!

EDIT: If you’re looking for docs we now have some auto-generated docs that you can view in your terminal. View this post.

node recap #2

JSONSelect

This first library is JSONSelect. This library allows you to query JSON using css selectors! this seems like an obvious one, but I haven’t personally seen any other implementations.

It’s not node-specific, however it is JavaScript, so naturally it works with nodejs as well, and over all it’s just a neat concept. Suppose we have the following JSON:

JSONSelect

  {
      "name": {
          "first": "Lloyd",
          "last": "Hilaiel"
      },
      "favoriteColor": "yellow",
      "languagesSpoken": [
          {
              "language": "Bulgarian",
              "level": "advanced"
          },
          {
              "language": "English",
              "level": "native"
          },
          {
              "language": "Spanish",
              "level": "beginner"
          }
      ],
      "seatingPreference": [
          "window",
          "aisle"
      ],
      "drinkPreference": [
          "whiskey",
          "beer",
          "wine"
      ],
      "weight": 172
  }

To grab the languages “Bulgarian”, “English” and “Spanish” we could issue the following query:

.languagesSpoken .language

cool!

node-canvas Image#src=Buffer

A few days ago I added support to node-canvas for Image#src= to accept Buffer objects, not only path strings. This needs to be polished, and to increase format support but we can finally apply image data from arbitrary sources:

 var buf = fs.readFileSync(__dirname + '/textures/jpeg');
 var img = new Image;
 img.src = buf;
 ctx.drawImage(img, 0, 0, 400, 400);

When the Buffer is assigned we can sniff the bytes to determine the format by looking for the “magic number”. For example a PNG starts with the following bytes “89 50 4e 47 0d 0a 1a 0a”, while a JPEG starts with “ff d8”.

Express 2.3.8

A recent Express refactor moved Connect’s router middleware into Express so that I could modify it further. This also means that Connect 2.0 will no longer have router. At first it seemed like a good idea, but routing to specific and it gives people the wrong idea, Connect is meant to be an abstraction layer for higher level frameworks, not to be used directly for application logic. Though this is not true for all cases, such as simply serving static files from a directory or two.

This commit consists of a general refactor of the router, while retaining the public API. What does this mean for Express? flexibility! For example now we may query Express to see which (if any) routes match a specific route path:

 app.get('/user/:id');
 // => [Route]

or routes that match any HTTP method:

 app.all('/user/:id');
 // => [Route, Route, Route]

this is functionally equivalent to:

 app.lookup.all('/user/:id');

Another alternative is “matching” rather than “lookup”. With app.match.VERB() we can query Express to see which routes would match the url passed, for example:

app.match.get('/user/12/edit');
// => [Route]

app.match.del('/user/12');
// => [Route]

app.match.all('/user/12?foo=bar');
// => [Route, Route]

In this commit I’ve introduced the ability to register logic for defining parameters. Within Express core we only support middleware-style param pre-conditions, for example auto-loading a user for any route that includes the :uid param:

app.param('uid', function(req, res, next, uid){
  User.find(uid, function(err, user){
    if (err) return next(err);
    req.user = user;
    next();
  });
});

app.get('/user/:uid, function(){
  // req.user
});

while this is great, some cases can be less verbose, while still expanding to middleware-style functions, this is where express-params comes in. This plugin extends Express with additional app.param() logic, for example via RegExp:

  app.param('uid', /^[0-9]+$/);

  app.get('/user/:uid', function(req, res, next){
    var uid = req.params.uid;
    res.send('user ' + uid);
  });

  app.get('/user/:name', function(req, res, next){
    var name = req.params.name;
    res.send('user ' + name);
  });

or via return value, useful for validations and coercion:

  app.param('id', Number);

  app.get('/user/:id', function(req, res, next){
    var id = req.params.id;
    res.send('typeof ' + typeof id + ' ' + id);
  });

Fabric.js

This one is not node related, but I wanted to sneak it in :) Fabric is a slick client-side library providing an object model on top of canvas. It has a built-in drawing mode and path smoothing, SVG parsing and some other really cool features. If you do a lot of canvas work it’s worth checking out, the author did a good job at keeping the source clean and commented, which is very important when utilizing open source.

fabricjs

node-migrate

node-migrate is a very small abstract migration framework. All it cares about is that you supply an up() and down() method, and invoke the callback when your migration is complete:

 exports.up = function(next){
   next();
 };

 exports.down = function(next){
   next();
 };

node-migrate comes with the migrate(1) executable, allowing you to run and create migrations, for example here we add two migrations, populating ./migrations/0-add-pets.js etc.

 $ migrate create add-pets
 $ migrate create add-owners

The contents of our badass pet adding migration might look something like this:

 var db = require('./db');

  exports.up = function(next){
    db.rpush('pets', 'tobi');
    db.rpush('pets', 'loki');
    db.rpush('pets', 'jane', next);
  };

  exports.down = function(next){
    db.rpop('pets');
    db.rpop('pets', next);
  };

Now all we have to do is run the migrations:

 $ migrate
 up : migrations/0-add-pets.js
 up : migrations/1-add-jane.js
 up : migrations/2-add-owners.js
 up : migrations/3-coolest-pet.js
 migration : complete

The next time we run migrate, we’ll see that they have already been completed:

 $ migrate
 migration : complete

For more information check out the GitHub repo.

Move.js

The other night I noticed that Apple’s new iMac page showcased some really slick CSS3 animations, and wanted a really simple and intuitive way to create similar effects so I came up with Move.js.

Below is an example of the API:

move('#example-13 .box2')
  .set('background-color', 'red')
  .x(500)
  .scale(.5)
  .rotate(60)
    .then()
      .rotate(30)
      .scale(1.5)
      .set('border-radius', 5)
      .set('background-color', 'white')
      .then()
        .set('opacity', 0)
        .pop()
      .pop()
  .end();

It’s still in it’s early stages, and I don’t have much in the way of documentation yet however feel free to check out the site as well as the examples in the repository.

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);

Express 1.0beta

Yesterday I released Express 1.0.0beta, a Sinatra inspired Node web development framework.

The beta is a near re-write consisting of roughly 300 commits, introducing new features, removing legacy code, and improving documentation. Express now runs on the Connect middleware framework, which replaces the previous concept of a Plugin. The performance of express has also been optimized and can now respond much faster than previous versions.

Connect

By abstracting the Express Plugin’s to a specific middleware framework, the community can now build on, and utilize this functionality to power their own frameworks. Connect currently provides:

  • bodyDecoder Buffers and parses json and urlencoded request bodies (extenable)
  • conditionalGet Provides 304
  • errorHandler Handles exceptions thrown, or passed through the stack
  • debug Outputs debugging console to all html responses
  • format Handles url path extensions or
  • gzip Compresses response bodies with gzip executable
  • lint Aids in middleware development
  • logger Provides common logger support, and custom log formats
  • methodOverride Provides faux HTTP method support via the _method param
  • responseTime Responds with the X-Response-Time header in milliseconds
  • compiler Supports arbitrary static compilation of files, currently supports less and sass.
  • cacheManifest Provides cache manifest for offline apps
  • jsonrpc Provides JSON-RPC 2.0 support
  • staticProvider Serves static files
  • cookieDecoder Provides cookie parsing support
  • session Provides session support
  • cache Provides memory caching
  • pubsub Publish subscribe messaging support
  • repl Read Evaluate Print Loop attached to
  • vhost Virtual host support

Performance Enhancements

Express is now much faster, with a concurrency of 80, and 8000 it can easily serve the typical “Hello World” response with ~10,000 requests per second on my machine. Ruby’s Thin (1.2.7) by comparison serves ~6500 rps. Finally by adding Sinatra in the mix I get ~1900 rps.

These numbers are to be taken lightly of course, and are simply relative, to re-cap:

Express        ~10,000
Rack/Thin      ~6,500
Rack/Sinatra   ~1,900

Graph for fun:

express vs sinatra

Documentation Overhaul

The new docs include a 1.x Migration Guide which should cover most of the changes that would be required to get you up and running. Another thing worth mentioning is that the docs are now generated via Markdown, and are located within ./docs which provides an easy way for developers to contribute docs.

I also have a Contrib Guide for those who are interested in helping Express out, and of course a completely revamped developers Guide.

For those who like to dig in deep and check out internals, my dox project generates the annotated source for Express.

Application Generating Executable

Express now ships with the express executable, creating app skeletons with a single tiny command:

$ express

thats it! of course view —help for more information.

Future of Express

From now on Express is clutter-free, no more dependencies on random extension libraries, no more high level http client library, just simply performance, routing, responding, configuration, and views. Feel free to post an issue if you find a bug, or have suggestions for focused features that you would like to see in the framework.

Looking forward to 1.0, Happy Express-ing everyone :)