Middlewares no Express: Tudo que você precisa saber!
Podemos falar que middlewares são, Funcões que rodam entre o objeto request
e o response
de uma aplicação. Com eles, podemos executar qualquer
código durante esse processo, encerrar o response ou até mesmo modificar os
objetos req e res.
Escrevendo um Middleware simples
Vamos escrever uma função chamada simpleMiddleware como nosso middleware, e depois disso, usaremos app.use(simpleMiddleware) para nosso app.get('/') ter acesso à ela.
_15const express = require('express')_15const app = express()_15_15const simpleMiddleware = (req, res, next) => {_15 console.log('Middleware funcionando!')_15 next()_15}_15_15app.use(simpleMiddleware)_15_15app.get('/', (req, res) => {_15 res.send('<h1>Hello World!</h1>')_15})_15_15app.listen(3000)
Quando acessamos http://localhost:3000/ vamos receber a mensagem "Middleware funcionando!". Perceba que não vamos receber o console.log() no browser, o Node.js roda no V8 Engine do JavaScript e não tem acesso ao nosso browser!
Usando um Middleware: Global
No exemplo acima, usamos app.use(), se por acaso temos mais rotas neste arquivo, o Middleware será usado em todos, por isso chamados de uso global. É importante resaltar que eles são chamados na ordem que são definidos. Veja o exemplo:
_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...
O nosso Middleware apenas será chamado caso hajá alguém acessando a página http://localhost:3000/About, a página principal será ignorada. O uso global pode ser útil quando organizamos as rotas por arquivos e tipos!
Usando um Middleware: Rota
Caso queira usar por rota, você pode adicionar o nome do Middleware entre os objetos req e res. Veja o exemplo
_7..._7_7app.get("/", simpleMiddleware, (req, res) => {_7 res.send("<h1>Hello World!</h1>");_7});_7_7...
ou assim
_7..._7_7app.get("/", (req, res, next) => {_7 res.send("<h1>Hello World!</h1>");_7});_7_7...
Preferência por Middlewares: Global vs Rota
Saiba que quando usamos app.use(middleware), ele tem uma preferência maior que o por rota, ou seja, ele irá ser chamado primeiro.
_8app.use(myGlobalMiddleware)_8_8app.get('/about', myRouteMiddleware, (req, res) => {_8 res.send('About page')_8})_8_8// myGlobalMiddleware é chamado_8// myRouteMiddleware é chamado
Comunicação entre Middlewares
Podemos passar informações entre Middleware ao modificar os seus objetos req e res. Veja o exemplo
_12const autorizarMaioresDeIdade = (req, res, next) => {_12 if (req.query.idade >= '18') {_12 req.autorizado = true_12 next()_12 } else {_12 res.send('ERRO: Você é menor de idade')_12 }_12}_12_12app.get('/', autorizarMaioresDeIdade, (req, res) => {_12 res.send(`<h1>Página principal <br/> Autorizado = ${req.autorizado} </h1>`)_12})
Ao acessar com http://localhost:3000/?idade=18, o Middleware nos autoriza por termos os requisitos necessários, e logo depois, renderiza a página com a mensagem: Autorizado true.

Evite erros usando Middlewares
Nos exemplos anteriores, usamos um if e else para determinar se o usuário é maior de idade, mas e se quisermos "encurtar" o código com a intenção de deixá-lo mais limpo? A primeira coisa que alguém pensa é em deixar assim:
_7const autorizarMaioresDeIdade = (req, res, next) => {_7 if (req.query.idade >= '18') {_7 req.autorizado = true_7 next()_7 }_7 res.send('ERRO: Você é menor de idade')_7}
O express roda códigos mesmo depois do next(), portanto, o usuário seria autorizado e logo depois receberia um erro! Por mais chato que seja, essa maneira que o express usa em Middlewares abre mais uma oportunidade para que rodamos algum código após o objeto response.