Express Middlewares: Everything you need to know!

Artigo em Português

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.


_15
const express = require('express')
_15
const app = express()
_15
_15
const simpleMiddleware = (req, res, next) => {
_15
console.log('Middleware working!')
_15
next()
_15
}
_15
_15
app.use(simpleMiddleware)
_15
_15
app.get('/', (req, res) => {
_15
res.send('<h1>Hello World!</h1>')
_15
})
_15
_15
app.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
_13
app.get("/", (req, res) => {
_13
res.send("<h1>Hello World!</h1>");
_13
});
_13
_13
app.use(simpleMiddleware)
_13
_13
app.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
_7
app.get("/", simpleMiddleware, (req, res) => {
_7
res.send("<h1>Hello World!</h1>");
_7
});
_7
_7
...

or like this


_7
...
_7
_7
app.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.


_8
app.use(myGlobalMiddleware)
_8
_8
app.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


_12
const 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
_12
app.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:


_7
const 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.