Express

High performance, high class web development for Node.js

## Express

`migrate`

### Built On Connect

Express 1.x is written to run on-top of the Connect middlware framework, thus the Plugin has been replaced by Connect's middleware. By abstracting our middleware to Connect we allow additional community frameworks to develop robust, high-level frameworks using the same technologies as Express.

### Creating Applications

Previously due to legacy code implemented in the early days of node, Express unfortunately had some globals. The DSL would previously be accessed as shown below:

    require('express');

    configure(function(){
        // app configuration
    });

    get('/', function(){
        return 'hello world';
    });

Now we utilize the CommonJS module system appropriately, and introduce express.createServer() which accepts the same arguments as http.createServer():

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

    app.configure(function(){
        // app configuration
    });

    app.get('/', function(req, res){
        res.send('hello world');
    });

Express 1.x does not currently allow returning of a string.

### Plugins vs Middleware

Previously Express was bundled with plugins, which were essentially what are now Connect middleware. Previously plugins would be utilized in a manor similar to below:

    use(Logger);
    use(MethodOverride);
    use(Cookie);

Which we can now use() within our app, or pass to the express.createServer() method:

    var app = express.createServer(
        express.logger(),
        express.methodOverride(),
        express.cookieDecoder()
    );

or:

    var app = express.createServer();

    app.use(express.logger());
    app.use(express.methodOverride());
    app.use(express.cookieDecoder());

For documentation on creating Connect middleware visit Middleware Authoring.

### Running Applications

Previously a global function run(), was available:

    run();

The new express.Server has the same API as http.Server, so we can do things like:

    app.listen();
    app.listen(3000);

### Route Parameters

Previously we could use this.param() to attempt fetching a route, query string, or request body parameter:

    get('/user/:id', function(){
        this.param('id');
    });

Polymorphic parameter access can be done using `req.param()`:

    app.get('/user/:id', function(req, res){
        req.param('id');
    });

Route parameters are available via `req.params`:

    app.get('/user/:id', function(req, res){
        req.params.id;
    });

### Passing Route Control

Old express had a weak notion of route passing, which did not support async, and was never properly implemented for practical use:

    get('/', function(){
        this.pass('/foobar');
    });

Now Express has access to Connect's next() function, which is passed as the third and final argument. Calling next() will pass control to the next matching route, or continue down the stack of Connect middleware.

    app.get('/user/:id?', function(req, res, next){
        next();
    });

    app.get('/user', function(){
        // ... respond
    });

### View Rendering

View filenames no longer take the form Express.TYPE.ENGINE, the Content-Type can be set via res.contentType() or res.header(). For example what was previously layout.html.haml, should now be layout.haml.

Previously a view render looked something like this:

    get('/', function(){
        this.render('index.html.haml', {
            locals: { title: 'My Site' }
        });
    });

We now have res.render(), however the options passed to haml, jade, and others remain the same.

    app.get('/', function(req, res){
        res.render('index.haml', {
            locals: { title: 'My Site' }
        });
    });

Previously rendering of a collection via partial() would look something like this:

    this.partial('comment.html.haml', { collection: comments });

Although this worked just fine, it was generally to verbose, the similar but new API looks like this, as partial() is always passed as a local variable:

    partial('comment.haml', { collection: comments });

To make things even less verbose we can assume the extension when omitted:

    partial('comment', { collection: comments });

And once again even further, when rendering a collection we can simply pass an array, if no other options are desired:

    partial('comments', comments);

### Redirecting

Previously you would

    this.redirect('/somewhere');

However you would now:

    res.redirect('/somewhere');
    res.redirect('/somewhere', 301);

### HTTP Client

Previously Express provided a high level http client, this library is no more as it does not belong in Express, however it may be resurrected as a separate module.

### Core Extensions

Express is no longer dependent on the JavaScript Extensions library, so those of you using the methods provided by it such as `Object.merge(a, b)` will need to roll your own, or install the module via:

    $ npm install ext