The Nodesource Blog

#shoptalk Subscribe

What's New in Express 4

Express – the most popular web framework for Node – reached version 4.0 on the 9th of April, bringing with it a handful of backwards incompatible changes and general housekeeping.

In this article, we'll cover the large changes introduced in Express 4 that you'll need to be aware of when upgrading: the new, more versatile routing system, the removal of Connect as a dependency, the removal of the app.configure() method and a new generator for Express 4 applications.

More Flexible Routing

Express 4 introduces a number of changes and additions to improve routing, allowing for better organisation of routes in larger applications.

Routing is now exposed at the highest level in Express 4. Applications no longer need to explicitly make their app use Express's router via app.use(app.router) – it's now integrated directly into your application

Express 4 also contains some syntactical improvements to routing. It's common to handle more than one HTTP verb for a single route, especially so if your application is serving a RESTful API. To achieve this in Express 3, you would have to write similar code to the following:

app.post("/test", testRoute.post); // register POST handler for /test
app.get("/test", testRoute.get);   // register GET handler for /test
app.put("/test", testRoute.put);   // register PUT handler for /test

Express 4 supports a new, fluid API, allowing you to organise your application into single endpoints via a new Router object. The example above can be rewritten as the following using a new method introduced, app.route():

app.route("/test")       // returns a Router object
   .post(testRoute.post) // register POST handler for /test
   .get(testRoute.get)   // register GET handler for /test
   .put(testRoute.put);  // register PUT handler for /test

Both approaches are functionally equivalent, and both are supported in Express 4.

Router objects can also be used to separate your application into smaller chunks. The object supports a subset of Express's regular API; for example, you could create a Router to handle user profile related aspects of an applicaition like so:

var express = require("express");
var profile = express.Router();

profile.get("/", function (req, res, next) {
    getCurrentUser(function(user) {
        res.send(user);
    });
});

profile.get("/:username", function (req, res, next) {
    var username = req.params.username;
    getSingleUser(username, function(user) {
        res.send(user);
    });
});

profile.post("/settings", function(req, res, next) {
    var error = {code: 501, message: "Not implemented"};
    res.status(error.code);
    res.render("error", error);
});

module.exports = profile;

You can use the Router in your Express 4 app by calling the app.use() method.

app.use("/profile", require("./routes/profile"));

Express will now serve requests to "/profile", "/profile/:username" and "/profile/settings".

For more information on the new Router API, be sure to check out the official documentation.

Farewell, Connect

Connect is a middleware layer for Node developed alongside Express, and it's been removed in this release. The middleware API is now integrated directly into Express, and as a result, every middleware previously provided by Connect has been removed from the core apart from express.static(), left for convenience purposes.

Having the ability to independently update middleware without bumping Express's version was one of the main motivations for the split. Each middleware now has it's own Git repository and maintainers, decluttering the Connect and Express repositories from individual middleware-based issues.

You can find out more about replacing Connect middleware with their npm module equivalents in Connect's documentation.

Environment-Dependent Configuration

Express 3 provided app.configure() to register functions to be executed based on what kind of environment your Express application was running in. This has been removed in Express 4 due to it being considered an unnecessary wrapper around a regular if statement to check the environment variable. In many cases, it's cleaner to either use a conditional to include custom logic based on the current environment, or in the case of middleware, pass different options into the constructor.

Previously, you may have had calls to app.configure() such as:

app.configure("development", function () {
    // code to run in development mode
});

In Express 4, this would be written as such:

if (app.get("env") === "development") {
    // code to run in development mode
}

New Generator

When installed globally, Express 3 would provide a command line utility to aid in generating new applications. Just like the middleware, this has been split out into a separate module, express-generator. This was done in line with the general rationale of Express 4: to clean up the main Express codebase.

If you've previously installed Express globally and want to make use of the Express 4 generator, uninstall express globally and install express-generator globally instead.

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

The generator will be available via the express command. For usage information, be sure to check out the help via express -h.

Other Breaking Changes

There are other minor – but backwards-incompatible – changes that you'll need to be aware of if you're upgrading an application from Express 3. You can find out more about migrating over at Express's official migration guide.

Should You Upgrade?

Express 4 is a very solid release, addressing many concerns and gripes users have come to experience with Express 3 in the context of application organisation and testing. Creating and testing routes for large applications in Express 3 could become messy without the use of modules such as express-enrouten; Express 4 makes the process easier by introducing the new Router API.

The changes brought about in the framework point Express in the direction of the Unix philosophy that's influenced a large amount of the Node community: "Small is beautiful ... Make each program do one thing well". Splitting the core framework and any other non-essential components into their own projects makes room for experimentation in middleware APIs, as well as the availability of new features at a quicker pace and a more flexible release schedule, without having to increment Express's version.

Upgrading from Express 3 to Express 4 should be a painless process using both this article as a reference and the official migration guide.

Express middleware released on npm will most likely target Express 4 from now onwards, and using them in your Express 3 applications could possibly cause issues due to API incompatibilities. If this is a concern, upgrading to Express 4 is recommended.