What is an Express Middleware and How to Create One

How to inspect, manipulate, and reject HTTP requests and responses with Express Middlewares

Keith Alpichi
Jul 20, 2017 · 4 min read
https://goo.gl/images/b2b3nr

Prerequisites

Basic understanding of the HTTP protocol, Javascript, Node, and Express

What are Middlewares?

From the documentation,

Middlewares are functions that have access to the request object (req), the response object (res), and the next function in the application’s request-response cycle. The next function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware.

To give you a relatable picture, Express middleware’s are the workers in a manufacturing line where each individual has a specific and unique responsibility. When a worker receives a product (request) from a previous worker they can do one of the following:

  • reject the product if it doesn’t meet strict standards, thus the product ceases to continue down the production line
  • add to or manipulate the product and/or allow the product to continue down the production line where the next worker (middleware) does their job

If you’ve used Express before, you may have used some middlewares:

  • body-parser- parses the request body and places it into the req.body key of the request object
  • express.static- serves your static files
  • express.logger- uses a logger

All you had to do was add these to your Express application or route and BAM… you had more functionality! It seemed like magic but it’s actually quite simple.

In this article I’ll go over the details of middlewares and some useful examples showcasing the flexibility and power of middlewares.

Req, Res, Next

Middlewares have access to three things:

Since you have access to the request and response you can do almost anything you want. You can extract or add information to and from either one. You would call next if you want to continue the request and pass it on to the next middleware or end the request right there.

Middleware Chain

So you created the custom middleware, now what? You add it to the middleware chain. Middlewares are called in the order they’re declared.

  • On every request these two middlewares will run- bodyParser will run first before the one below it
const apiRouter = express.Router()
apiRouter.use(customMiddleware2)
app.use(‘/api’, apiRouter)

You can have middlewares run on specific routes:

  • customMiddleware will run first followed by customMiddleware2 for the GET method on the path ‘/some/path’
  • Only customMiddleware2 will run for all requests to the apiRouter

Cool huh? Let’s see some other useful examples!

A Simple Logger- Log Date and URL Path

In this example I extract and log some data specific to the request, then pass the request to the next middleware by using the next function. The request or response is not altered in any way. I’ll show an example of that next.

A request to a url www.foo.com/bar would log

After the console.log function ran the next function was called. At this point the request and response would be handed to the next middleware.

Token Parser- Parse User ID from JWT Token

In this example I parse the request object for the JWT token to get the user’s id. If it doesn’t exist or the token was invalid I end the request and send back an unauthorized status code of 401. At this point the request stops. If it does exist I place the user’s id into req.user_id then call next.

Note that the key user_id is arbitrary. I could have used req.users_identification_number. However, there are reserved keys on the request and response object that you shouldn’t modify. So consult the documentation to verify you’re not modifying reserved keys.

  if (!user_id) {
res.sendStatus(401)
} else {
req.user_id = user_id
next()
}
}

Now in every succeeding middleware or request handler I have access to the user’s id at req.user_id.

Environment-specific Middleware

Since middleware’s are just functions you can have functionality based on different environments or configuration. Say, for example, we wanted to perform descriptive logging for development environments.

Then add this middleware by calling it with the environment

These may not be practical examples you’d actually use in production but the illustrations should provide some clarity on the flexibility of middlewares.

Beauty Of Middlewares

I love how the flow in Express middleware’s are very explicit. It makes code intuitive, super flexible, and easy to read. If you’re not creating custom middlewares I highly encourage you to take advantage of their simplicity and power.

If you have any comments or questions please leave a comment or tweet me! Mahalo! 🤙

)

Keith Alpichi

Written by

Software Engineer, Coffee Addict, Fit Fanatic, Cook, and California Beach Bum. See more @ http://keithalpichi.github.io/

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade