Express Middlewares: Everything you need to know!
We can say that middlewares are, Functions that run between the request
object
and an application's response
. With them, we can run any
code during this process, terminate the response or even modify the
req and res objects.
Writing a simple Middleware
Let's write a function called simpleMiddleware as our middleware, and after that, we'll use app.use(simpleMiddleware) for our app.get('/') to access it.
_15const express = require('express')_15const app = express()_15_15const simpleMiddleware = (req, res, next) => {_15 console.log('Middleware working!')_15 next()_15}_15_15app.use(simpleMiddleware)_15_15app.get('/', (req, res) => {_15 res.send('<h1>Hello World!</h1>')_15})_15_15app.listen(3000)
When we access http://localhost:3000/ we will get the message "Middleware working!". Note that we will not receive the console.log() in the browser, Node.js runs on the V8 Engine of the JavaScript and does not have access to our browser!
Using a Middleware: Global
In the example above, we use app.use(), if we happen to have more routes in this file, Middleware will be used in all, hence called global usage. It is important to note that they are called in the order they are defined. See the example:
_13..._13_13app.get("/", (req, res) => {_13 res.send("<h1>Hello World!</h1>");_13});_13_13app.use(simpleMiddleware)_13_13app.get("/about", (req, res) => {_13 res.send("<h1>About Page!</h1>");_13});_13_13...
Our Middleware will only be called if someone is already accessing the page http://localhost:3000/About, the main page will be ignored. Global usage can be useful when organizing routes by files and types!
Using a Middleware: Route
If you want to use it by route, you can add the Middleware name between the req and res objects. see the example
_7..._7_7app.get("/", simpleMiddleware, (req, res) => {_7 res.send("<h1>Hello World!</h1>");_7});_7_7...
or like this
_7..._7_7app.get("/", (req, res, next) => {_7 res.send("<h1>Hello World!</h1>");_7});_7_7...
Middleware Preference: Global vs Route
Know that when we use app.use(middleware), it has a higher preference than the route one, that is, it will be called first.
_8app.use(myGlobalMiddleware)_8_8app.get('/about', myRouteMiddleware, (req, res) => {_8 res.send('About page')_8})_8_8// myGlobalMiddleware is called_8// myRouteMiddleware is called
Communication between Middlewares
We can pass information between Middlewares by modifying its req and res objects. See the example
_12const authorizeMajorAge = (req, res, next) => {_12 if (req.query.age >= "18") {_12 authorized.req = true;_12 next();_12 } else {_12 res.send("ERROR: You are a minor");_12 }_12};_12_12app.get("/", authorizeMajorAge, (req, res) => {_12 res.send(`<h1>Main page <br/> Authorized = ${authorized request} </h1>`);_12});
When accessing with http://localhost:3000/?age=18, the Middleware authorizes us to have the necessary requirements, and soon after, renders the page with the message: Authorized true.

Avoid errors using Middlewares
In the previous examples, we used a if and else to determine if the user is a minor or not, but what if we want to "shorten" the code with the intention of making it cleaner? The first thing someone thinks about is leaving it like this:
_7const authorizeMajorAge = (req, res, next) => {_7 if (req.query.age >= '18') {_7 authorized.req = true_7 next()_7 }_7 res.send('ERROR: You are a minor')_7}
express runs code even after next(), so the user would be authorized and then get an error! As annoying as it is, this way that express uses in Middlewares opens up another opportunity for us to run some code after the
response object.