What is Middleware? A simple explanation.

What is Middleware? A simple explanation.

If you’ve used Ruby on Rails, Sinatra, Express.js or any other modern web framework, you’ve likely encountered the term Middleware. In this short post I’ll explain what middleware is, and how to write your own. Most of my explanation will be in the context of a Node.js Express web server.

What problem does middleware solve? Why would I use it?

Any time you type a url into your browser (the client) address bar, you are requesting information from a web server. This web server then sends a text response back to the your browser. The browser then interprets and converts that text response into text content, styling, images or even video.

Say you’re running a web application on a web server with Node.js and Express. In this application, let’s say you certain pages that require that you log in.

When the web server receives a request for data, Express gives you a request object with information about the user and the data they are requesting. You can see their IP address. What language their browser is set to. What url they are requesting, and what parameters they have passed along. Express also gives you access to a response object that you can modify before the web server respond to the user. These objects are usually shortened to req, res.

Middleware functions are the perfect place to modify the req and res objects with relevant information. For instance, after a user has logged in, you could fetch their user details from a database, and then store those details in res.user.

In short, middleware gives you access to req and res in the apps request-> response cycle.

What does a middleware function look like?

A middleware function example from the Express docs: https://expressjs.com/en/guide/using-middleware.html

There are several important things to point out here:

  1. Middleware functions usually have 3 standard params req, res, and next. The first two are objects, the last is a function that will call the next middleware function, if there is one.
  2. Usually there is a middleware chain, meaning a chain of functions that are called one after the other, with the last function sending the response back to the browser. So we get the request from the browser, make any modifications and data additions, and then send a response back.
  3. You must call next() (unless it’s the last function in the chain) or the request will just hang and eventually timeout. In the browser this will manifest as a really long spinner before a message of “connection timed out” or similar.
  4. Any changes you make to req or res will be available in the next middleware function.
  5. req and res are unique for each request. Meaning that a user from USA result in a different req object than a user from a European country.

How do I use existing middleware?

If you’re using Express, you’re likely already using middleware. There are many Express middleware function available.

Say for instance that we wanted to record how long each request takes to be sent back to the browser. We’d add the existing middleware function for that:

Example of using the response-time middleware: https://expressjs.com/en/resources/middleware/response-time.html

How do I write my own middleware for certain routes?

This is where middleware is the most useful in my opinion.

Authentication middleware redirects a user back to a login page if they are not logged in

When we run the above code, and request the /user/someName route, the server will check to see if the user is already logged in. If they are not, the server tells the browser to redirect to the /login route.

In conclusion

Middleware functions are a really great way to run code on each request, or on each request for a certain route, and to take action on request or response data. Middleware is a crucial piece of any modern web server, and is incredibly useful.

Published 24 Jun 2018