Creating Your Own Express.js Middleware

Keenan Jaenicke

Have you found yourself repeating the same code at the beginning of an Express.js route handler? Perhaps you want to log the path for each incoming request to your application or prevent a user from performing a certain operation. These are prime examples where a custom Express.js middleware would do the trick!

Middleware in Express.js are a powerful, elegant way of handling common functionality in you applications. A couple of popular middleware that you’ve likely already used are body-parser (used for parsing a JSON request body) and cors (enables CORS support for your application). These packages provide huge value and are incredibly easy to configure, largely in part due to the beauty of Express.js’s middleware system.

Getting Started

You’ll need to have Node.js installed first, of course. You can do that here. You will also need to have an Express.js application set up. You can follow along here to get yours set up.

Anatomy of an Express Middleware

Express.js middleware are functions that have the following signature:

function myCustomMiddleware(req, res, next) {
  // custom middleware here...
}

The req parameter here is an Express.js request object (learn more about the Express.js request object here). The res parameter is an Express.js response object (learn more about the Express.js response object here). Lastly, the next parameter is a function that tells Express.js to continue on to the next middleware you have configured for your application.

Middleware have the ability to modify the req or res objects, run any code you wish, end the request-response cycle, and call the next middleware in the stack. Due to “chaining” style of the middleware stack in Express.js, where each proceeding middleware is required to call next() before moving on, the order in which the middleware are added is of the utmost importance.

Modifying the   req   Object

Suppose you want to identify the currently logged in user on every request. You could write a middleware that would fetch the user (user lookup will depend largely on your authentication method) that would something like so:

middleware/setCurrentUser.js

// getUserFromToken would be based on your authentication strategy
const getUserFromToken = require("../getUserFromToken");

module.exports = function setCurrentUser(req, res, next) {
  // grab authentication token from req header
  const token = req.header("authorization");

  // look up the user based on the token
  const user = getUserFromToken(token).then(user => {
    // append the user object the the request object
    req.user = user;

    // call next middleware in the stack
    next();
  });
};

Once you have your shiny new middleware ready to go, you’ll need to add it to your application. This can be done quite simply by “using” the middleware, like so, which enables the middleware for all routes in your application:

server.js

const express = require('express');
const setCurrentUser = require('./middleware/setCurrentUser.js');

const app = express();

app.use(setCurrentUser);

// ...

Modifying the   res   Object

Suppose you want to always set a custom header on your response object. This can easily be achieved via a middleware like so:

middleware/addGatorHeader.js

module.exports = function addGatorHeader(req, res, next) {
  res.setHeader("X-Gator-Policy", "chomp-chomp");
  next();
};

Ending the Request/Response Cycle

A common use case for a middleware is to validate that the user object has been set on your req object. You’re able to do this check and if the user is not found, terminate the request/response cycle, returning an authorized response. Below is a simple example of this approach:

middleware/isLoggedIn.js

module.exports = function isLoggedIn(req, res, next) {
  if (req.user) {
    // user is authenticated
    next();
  } else {
    // return unauthorized
    res.send(401, "Unauthorized");
  }
};

Once you have this middleware implemented, you’ll want to add it to your application’s middleware stack. Ordering is very important here! We will combine our earlier example of setting the user via our setCurrentUser middleware and then apply our new middleware. Additionally, we’ll only require the user be authenticated when using a single route, instead of application-wide.

server.js

const express = require("express");

const setCurrentUser = require("./middleware/setCurrentUser.js");
const isLoggedIn = require("./middleware/isLoggedIn.js");

const app = express();

app.use(setCurrentUser);

app.get("/users", isLoggedIn, function(req, res) {
  // get users...
});

With this example only the /users path will require that the user be authenticated.

Conclusion

With these simple functions we are able to encapsulate application logic that can be reused and is easier to reason about.

For further reading on writing custom Express.js middleware see the official docs.

  Tweet It

🕵 Search Results

🔎 Searching...

Sponsored by #native_company# — Learn More
#native_title# #native_desc#
#native_cta#