Categories
Express Node.js

How can I handle common checks across different endpoints in an Express application?

3 min read

Express is a routing and middleware web framework that has minimal functionality of its own: An Express application is essentially a series of middleware function calls.

Source: Express guide: Using middleware

It’s quite common if you’re building an API which serves and manipulates private data that you’ll want to check that a client has authorization to access specific API endpoints. Express has a powerful feature which can help you achieve this (or any other kind of common check): middleware functions.

Middleware functions are a fundamental concept in Express – they have access to the request object (commonly named req) and the response object (commonly named res) and they can run any code that you like. The best part is that you can tell Express to run the same middleware function for different routes, enabling you to do things like making a common check across different endpoints.

This code demonstrates how you can write your own Express middleware function, using the example of checking that clients are authorized to make requests to specific API endpoints:

const express = require("express");

/**
 * Custom middleware to check that a request is authorized.
 *
 * The API would need to provide an endpoint e.g. `/authenticate`
 * which clients can use to authenticate themselves and receive
 * a JSON Web Token. They would then send this in the `Authorization`
 * header of subsequent requests to the API and this middleware
 * would verify that it is valid.
 *
 * @param {Object} request - Express request object 
 * @param {Object} response - Express response object
 * @param {Function} next - Express next function
 */
function verifyJsonWebTokenMiddleware (request, response, next) {
	const authorizationHeader = request.get('authorization');
	const jsonWebTokenIsValid = verifyJsonWebToken(authorizationHeader);

	if (jsonWebTokenIsValid) {
		/**
		 * The JSON Web Token is valid so we call the `next()`
		 * function to tell Express to run the next middleware.
		 * In this example it's whichever function has been
		 * defined as the route handler.
		 */
		return next();
	}
	
	/**
	 * The JSON Web Token is invalid so we're sending an
	 * error response to the client, and Express won't run
	 * any other middleware because we're not calling the
	 * `next()` function.
	 * 
	 * HTTP status is 401 Unauthorized (https://httpstatuses.com/401).
	 */
	return response.status(401).json({
		error: 'unauthorized',
		message: 'Invalid JSON Web Token. Request unauthorized.'
	});
}

/**
 * This function would contain code which verifies the
 * JSON Web Token that has been passed in the `Authorization`
 * header and would return true if it is valid, rather than
 * always returning false.
 */
function verifyJsonWebToken(authorizationHeader) {
	return false;
}

/**
 * Express configuration and routes
 */

const PORT = 3000;
const app = express();

/**
 * No other middleware will be run for this route.
 *
 * This would be the endpoint which authenticates a client
 * agaist a database and responds with a JSON Web Token.
 */
app.post('/authenticate', (request, response) => {
	response.json({ token: 'json-web-token' });
});

/**
 * Tell Express that we want every route which we define
 * after this to run this middleware function first.
 */
app.use(verifyJsonWebTokenMiddleware);

app.get('/user/:id', (request, response) => {
	response.json({ name: 'Some Person' });
});

app.put('/user/:id', (request, response) => {
	response.status(202).json({ status: 'updated' });
});

app.listen(PORT, () => console.log(`Example app listening at http://localhost:${PORT}`));

Note: In this example you might have noticed that I refer to req as request and res as response. You can name the parameters for your middleware functions whatever you like, but I prefer verbose variable names as I think that it makes it easier for other developers to understand what your code is doing, even if they’re not familiar with the Express framework.

Express is very flexible, so as well as writing your own middleware, you can also use third-party middleware. Express also gives you options for different ways to apply middleware in your application. I fully recommend that you take a look at the links below if you want to learn more.

Continue your learning about Express middleware

One reply on “How can I handle common checks across different endpoints in an Express application?”

This was really helpful! Definitely being added to my bookmarks so I can refer to this next time I’m creating an express app with middleware.

Leave a Reply

Your email address will not be published. Required fields are marked *