Let's round out the walkthrough of app.js by discussing what middleware functions do for our application. We have an example at the end of the script:
app.use(function(req, res, next) {
var err = new Error('Not found');
err.status = 404;
next(err);
});
The comment says catch 404 and forward to error handler. As you probably know, an HTTP 404 status means the requested resource was not found. We need to tell the user their request wasn't satisfied, and maybe show them a picture of a flock of birds pulling a whale out of the ocean. This is the first step in doing so. Before getting to the last step of reporting this error, you must learn how middleware works.
We do have a middleware function right in front of us. Refer to its documentation at http://expressjs.com/en/guide/writing-middleware.html.
Middleware functions take three arguments. The first two, request and response, are equivalent to the request and response of the Node.js HTTP request object. However, Express expands the objects with additional data and capabilities. The last, next, is a callback function controlling when the request-response cycle ends, and it can be used to send errors down the middleware pipeline.
The incoming request gets handled by the first middleware function, then the next, then the next, and so on. Each time the request is to be passed down the chain of middleware functions, the next function is called. If next is called with an error object, as shown here, an error is being signaled. Otherwise, the control simply passes to the next middleware function in the chain.
What happens if next is not called? The HTTP request will hang because no response has been given. A middleware function gives a response when it calls functions on the response object, such as res.send or res.render.
For example, consider the inclusion of app.js:
app.get('/', function(req, res) { res.send('Hello World!'); });
This does not call next, but instead calls res.send. This is the correct method of ending the request-response cycle, by sending a response (res.send) to the request. If neither next nor res.send is called, the request never gets a response.
Hence, a middleware function does one of the following four things:
- Executes its own business logic. The request logger middleware shown earlier is an example.
- Modifies the request or response objects. Both the body-parser and
cookie-parser do so, looking for data to add to the request object. - Calls next to proceed to the next middleware function or else signals an error.
- Sends a response, ending the cycle.
The ordering of middleware execution depends on the order they're added to the app object. The first added is executed first, and so on.