Express Web Application Development
上QQ阅读APP看书,第一时间看更新

Empowering Express with middlewares

In Chapter 1, What is Express?, we learned about Express middlewares and saw how to create one. Now, let's go find out how to include one in our app. Remember we use app.use() for including middlewares.

Though we can write our own middlewares, we will focus on using one of the middlewares that comes bundled with Express.

For your reference, the following is the list of the middlewares that are available in Express, by default:

So there you have it, the list of middlewares available to you by default. For this example, we will use the responseTime middleware.

Modify app.js to use this middleware:

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

app.set('view engine', 'jade');
app.set('views', './views');

app.use(express.static('./public'));
// Add the responseTime middleware
app.use(express.responseTime());

app.get('/', function(req, res) {
  res.render('index');
});

http.createServer(app).listen(3000, function() {
  console.log('App started');
});

Restart the server. Load up the app in the browser and look at the HTTP response headers in any network traffic analyzer (I am using Google Chrome's Developer Tool):

When we enable the responseTime middleware, Express sends the time taken to process a request in the HTTP response header (X-Response-Time). You can see it highlighted in the preceding screenshot.

Now let's try using the errorHandler middleware. For test purposes, we will generate an error in the home page's route handler by calling an undefined function. According to the errorHandler middleware's description, it should format the error into a nice looking HTML page.

Edit app.js to include the middleware and generate the error:

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

app.set('view engine', 'jade');
app.set('views', './views');

app.use(express.static('./public'));
app.use(express.responseTime());
// Add the errorHander middleware
app.use(express.errorHandler());

app.get('/', function(req, res) {
  // Call an undefined function to generate an error
  fail();
});

http.createServer(app).listen(3000, function() {
  console.log('App started');
});

Restart the server and load the home page, you'll get an error message, as shown in the following screenshot:

The output doesn't look like an HTML page at all! In fact, you can confirm it is not HTML by looking at the source code. Why is the errorHandler middleware not working?

In the beginning of this chapter, I mentioned that unless you add the router middleware explicitly, it will be added at the point where a route is defined. The most important requirement of errorHandler is that it should be added after the router middleware. No wonder it didn't work as expected.

So now it makes sense to explicitly add the router middleware if we want to use errorHandler productively. You never know which other middleware might require router to be defined beforehand, so let's modify app.js to include the router middleware explicitly:

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

app.set('view engine', 'jade');
app.set('views', './views');

app.use(express.static('./public'));
app.use(express.responseTime());
// Explicitly add the router middleware
app.use(app.router);
// Add the errorHander middleware
app.use(express.errorHandler());

app.get('/', function(req, res) {
  // Call an undefined function to generate an error
  fail();
});

http.createServer(app).listen(3000, function() {
  console.log('App started');
});

Now restart the server, refresh the home page, and see the output:

This time the errorHandler middleware is doing what it is supposed to do.

Like errorHandler, you can use other middlewares whenever you might need them. By default, Express doesn't do a lot, but using its middleware you can make it do many other useful things.

As we saw earlier, you can write you own middleware, if you want. Anything you want to do with req and the res object, middleware is the way to go.