Express Middleware

When an Express server receives an HTTP request, it executes a list of middleware functions. The middleware functions are responsible for handling the request and crafting a response.

You will usually see middleware defined as a function with 3 parameters: req , res , and next . The biggest exception to this rule is error handling middleware. To add a middleware function to your Express app, you call app.use() .

const app = require ( 'express' )(); app.use( ( req, res, next ) => { req; res; next; });

Under the hood, when you call app.use() , Express adds your function to its internal middleware stack. Express executes middleware in the order they're added, so if you call app.use(fn1); app.use(fn2); , Express will execute fn1 before fn2 .

Middleware vs Route Handlers

Suppose you have a simple Express server that responds to GET requests with the string 'Hello, World' as shown below.

const app = require ( 'express' )(); app.get( '/' , function routeHandler ( req, res ) { res.send( 'Hello, World' ); });

In Express, a route handler is just a special type of middleware that never calls next() . You could also write a middleware that does the same thing.

app.use( function ( req, res, next ) { if (req.method !== 'GET' || req.url !== '/' ) { return next(); } res.send( 'Hello, World' ); });

Routing

The app.use() function takes 2 parameters: an optional path , and a middleware function callback . If the first parameter to app.use() is a string, Express will only execute the corresponding middleware function if the URL matches.

app.use( '/' , function middleware ( req, res, next ) { if (req.method !== 'GET' ) { return next(); } res.send( 'Hello, World' ); });

The next() Function

If you have multiple middleware functions, you need to make sure your middleware either calls next() or send a response. If you write Express middleware, this is your responsibility. Express will not throw an error if your middleware doesn't call next() , it will simply hang.

app.use( '/' , function middleware ( req, res, next ) { console .log( 'Test' ); });

In general, it is best practice to call next() unless you explicitly do not want the rest of the middleware stack to run. Calling next() if there's no more middleware is perfectly fine.

app.use( ( req, res, next ) => { res.send( 'Hello, World' ); next(); });

If you call next() with a parameter, Express will treat that parameter as an error and trigger error handling middleware. The below middleware will cause Express to respond with an HTTP 500 and a stack trace.

app.use( ( req, res, next ) => { next( new Error ( 'Fail!' )); });

If you open the above middleware in Chrome, you'll see something like this:

Want to become your team's Express expert? There's no better way to really grok a framework than to write your own clone from scratch. In 15 concise pages, this tutorial walks you through how to write a simplified clone of Express called Espresso. Get your copy!



Espresso supports: Route handlers, like `app.get()` and `app.post()`

Express-compatible middleware, like `app.use(require('cors')())`

Express 4.0 style subrouters As a bonus, Espresso also supports async functions, unlike Express.



Get the tutorial and master Express today!

More Express Tutorials