One core aspect of Express is the concept of middleware. A middleware is a piece of code in the middle - between the request and the response.
Itâs not absolutely required to use middleware. So itâs not the most important topic to learn early. But almost all Express projects make use of middleware, and the general concept doesnât take too long to explain. Itâs also a useful feature to know for upcoming lessons.
What is a middleware
Middlewares are JavaScript functions that run on the server whenever a request comes in but before the route function is executed. You generally use them for things that affect multiple or all routes of your platform.
Building a logger middleware
To best understand how middleware works, letâs build our own basic middleware. One of the most common middleware in applications is a logger. A logger is used to print in the console or write to so-called logfiles any activity on the server youâd like to keep track of.
Usually, at the bare minimum, people will log whenever a request comes in, paired with some information about it. So weâll do exactly that.
In the root folder of your project, create a new folder called middleware. In it, add a file called logger.js.
đĄ There are varying standards for how to organize the code of your project. You donât have to use a folder called âmiddlewaresâ. You can even write your middlware code write in the app.js file. Using a separate folder is generally a good idea, though, to keep your code more readable. Calling that folder âmiddlewaresâ is one common way to do it. So thatâs why itâs suggested here.
A middleware function looks very much like a route function with one addition. Here is our logger function that you can add to the middlewares/logger.js file:
export const logger = (request, response, next) => {
console.log(
new Date().toUTCString(),
'Request from',
request.ip,
request.method,
request.originalUrl
)
next()
}
If you didnât know yet: You can add multiple parameters to the same console.log()
and they will all be printed out within the same line and separated by spaces.
In our example, I print the current date and time with new Date().toUTCString()
(a built-in JavaScript function to get the current time and date in a human-readable format). Then, I print the string Request from
, followed by the IP address of the client (one of the many useful properties of the request
object), and lastly, the HTTP method** (request.method
) and the path that the client has requested with request.originalUrl
.
As you can see, you have access to the same request
and response
objects that you also have in route functions. But there is one more parameter that you may not know yet: next
.
The next
parameter is a function. So it has to be called with parentheses like this: next()
. The next()
function represents all the functions that will be executed after this middleware. It tells Express to move on either to the next middleware (if there are multiple) or to move on to execute the route function now.
đĄ Itâs important to keep in mind, though:
next()
is not the same as areturn
statement. So it does not stop the function. So you could even put it before theconsole.log()
and theconsole.log()
would still be executed - just after the followup code (such as other middlewares or route functions) are executed.This functionality can be useful whenever you want to have a middleware perform some code that is not needed for the response and can just run in parallel to the rest of the application and in the background.
To actually use the middleware, you need to first import it into your app.js file:
import { logger } from './middlewares/logger.js'
Then, before the route functions but somewhere below the const app
, add the following line:
app.use(logger)
Thatâs it. Thatâs all it takes to add the middleware to your application. If you now make requests to your server, you should start seeing in the Terminal lines pop up that looks like this:
Thu, 11 Aug 2022 07:37:16 GMT Request from ::1 GET /
Thu, 11 Aug 2022 07:37:17 GMT Request from ::1 GET /cookies
Thu, 11 Aug 2022 07:37:20 GMT Request from ::1 GET /cookies/chocolate-chip
đĄ The IP address just says
::1
because I access the server from the same computer. If you were to access the server from another computer, it would show another IP address.
Third-Party Middleware
In addition to writing your own middleware, there is a multitude of middleware written by others that you can use in your project. Express has various middlewares, including one that handles logging in a more comprehensive way - called morgan.
Another very popular middleware can be used for error handling, called errorhandler
You can find a complete list of Express middlewares plus some additional third-party middlewares in the official documentation. How you use each one of them should usually be documented in the middlewareâs documentation.
Recap
Thatâs already it. Middlewares donât do much other than adding some code logic in the middle between the request and the route functions. You can insert as many middlewares as you like. But the most common ones are probably related to logging and authentication.
đ How to practice
If you havenât already, as part of the lesson, add a logger middleware to the cookie shop.
To further practice the concept of middlewares, try to also add a logger to a separate project.