Express middleware plays a crucial role in the routing process. By creating custom functions, we can insert them at different points in the chain to perform specific operations.

Typically, middleware functions are used to modify the request or response objects or terminate the request before it reaches the route handler. These functions are added to the execution stack using the app.use() method, similar to defining a route.

For example:

app.use((req, res, next) => { /* middleware function */ })

In the above code snippet, we define a middleware function that takes three parameters: req (request object), res (response object), and next. The next parameter is a reference to the next middleware function in the stack, and we call next() at the end of our middleware function to pass the execution to the next handler.

However, if we want to prematurely end the response and send it back to the client, we can choose not to call next().

Express provides various pre-made middleware that can be installed via npm packages. You can find a comprehensive list of available middleware options here.

One such example is the cookie-parser middleware, which parses cookies into the req.cookies object. To use it, install the cookie-parser package using npm install cookie-parser and include it in your code as follows:

const express = require('express')
const app = express()
const cookieParser = require('cookie-parser')

app.get('/', (req, res) => res.send('Hello World!'))

app.use(cookieParser())
app.listen(3000, () => console.log('Server ready'))

In addition to adding middleware for all routes, we can also specify middleware functions to run for specific routes only. Simply pass the middleware function as the second parameter in the route definition:

const myMiddleware = (req, res, next) => {
  /* ... */
 next()
}

app.get('/', myMiddleware, (req, res) => res.send('Hello World!'))

If you need to store data generated in a middleware function and pass it down to subsequent middleware or the request handler, you can use the req.locals object. This object allows you to attach data to the current request:

req.locals.name = 'Flavio'

By leveraging Express middleware, you can enhance and customize your routing process according to your specific requirements.