← Back to all posts

Node Express 4

14 August 2014

Written by 


Richard Gubby


Earlier this year, version 4 of Express was released. It’s got a bunch of pretty big changes, so if you’re thinking of upgrading, you’re going to need to be aware of them. Hopefully at the end of this post you shouldn’t be too daunted when thinking of updating your version.


New Generator

First of all - the way you actually create Express apps has changed. When you installed Express 3 globally, you had a command line util available to scaffold out a new application. This has changed in version 4 and like the middleware changes detailed below, it’s now in its own separate module - called express-generator. If you want to install Express 4 globally, here’s how (and get rid of Express 3 while you’re at it).

npm uninstall -g express
npm install -g express-generator

The syntax for creating an app is the same as before (express myApp).

Middleware

All of the middleware that came bundled with Express 3 has moved into their own modules. bodyParser, json, favicon to name but a few have all changed and this allows them to receive their own updates, bug fixes and releases independently to the main Express release cycle. Here’s an example to demonstrate the syntax changes for using bodyParser between versions 3 and 4:

Express 3

package.json

{
    "dependencies":{
        "express":"~3.16.0"
    }
}

server.js

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

app.configure(function(){
    app.use(express.bodyParser());
});

Express 4

package.json

{
  "dependencies":{
    "express":"~4.8.0"
    "body-parser":"~1.6.4"
  }
}
var express = require('express'),
  bodyParser = require('body-parser');

app.use(bodyParser());

Router Improvements

Version 4 introduced a few new changes to the Router. Gone are the days of having to make your app use Express’ router via app.use(app.router) - it’s now available straight in your app.

There are also some syntactical improvements - so you can handle more than 1 verb for a single route (handling both GET & POST for example) - which helps when your application is serving a restful API. Here’s an example of how you can construct your routes in Express 4.

app.route('/user')
    .post(myUserRoute.post)
    .get(myUserRoute.get)
    .put(myUserRoute.put)

Much nicer! It helps to keep routes clean and DRY - it’ll also help to avoid spelling mistakes when typing in the same route a couple of times.

Running your App

If you ever looked inside your main app.js file in Express 3, you’d have seen a line that looked a bit like app.listen(3000);. This part of the app has been moved out of application files and into an executable JS file located at bin/www.

This file loads up your app.js file, (or whatever you call your application), sets a port if it hasn’t already been set and creates the server. If you look at the default start script inside of your package.json file, you’ll see that it references it by doing node ./bin/www.

A really nice side effect of this is that you can use something like SuperTest to hook right into your application to do integration tests without actually having to have the app running.

var supertest = require('supertest'),
    app = require('path/to/app.js'),
    api = supertest(app),
    expect = require('chai').expect;

describe('API test', function(){
    it('  - check response', function(done){
        api.get('/user')
            .expect('Content-Type', 'application/json')
            .expect(200)
            .end(function(err, res){
                expect(res.text).to.be.a('string');
                done();
            })
    }
}

In this example I’m using SuperTest and Chai to see if our /user path responds to a GET request with a content type of application/json, has a response code of 200 and the text that comes back is a string. All done without the app running - add a test like that into a gulp watch task so you can see if your code changes break your tests and your productivity should soar!

Environment dependent configuration

In Express 3 you had app.configure() to register functions to be executed based on what kind of environment your Express application was running in. It’s been removed in Express 4 and replaced with a simpler if check.

Version 3

app.configure('development', function(){
    // Code to run in dev mode
});

Version 4

if(app.get('env') === 'development'){
    // Code to run in dev mode
}

Should you upgrade?

In addition to everything listed above, there are a few other minor changes so it’s probably wise to check out the official Migration guide. I’ve also only listed a handful of middleware modules above that have moved out of Express, have a look at the full list at Connect Middleware and see if you need to make many changes to your app.

Express 4 has been out for over 5 months now with the latest release (at the time of writing) being 4.8.0 - it’s stable and addresses lots of concerns users have had about Express 3. If you’re looking to create a larger app with lots of routes or just want to stay up to date with current versions, then it’s about time you upgraded!

Comments on HN