Iniciando com middlewares no Express.js
Uma das principais funcionalidades dentro de frameworks web em Node.js é a utilização de middlewares. Hoje falaremos deles no Express.js, para entender como funciona fluxo de requisições e respostas que é totalmente baseado em middlewares, deixando as coisas mais interessantes.
Começando com middlewares
Para ficar mais claro, vou associar o Express a brincadeira de telefone sem fio. Sim, isso mesmo, mas o que uma coisa tem a ver com a outra? Bom o Express é aquele que passa a primeira informação e nela contém tudo que é relacionado ao serviços Web e a seus protocolos e métodos.
Vindo a primeira informação ela passa por uma fila, e assim como na brincadeira, o middleware pode alterar, adicionar ou apagarinformações. É importante dizer que no meio do caminho pode-se “acabar” com a brincadeira, como é o caso do res.render
, res.send
ou res.end
que emitem os cabeçalhos de respostas (protocolo HTTP). Vejamos esses códigos.
const express = require('express');
const app = express();
// Middleware #1
app.get('/', (req, res, next) => {
res.locals.hello = 'Hello World';
next();
});
// Middleware #2
app.get('/', (req, res) => {
return res.send(res.locals.hello);
});
// Middleware #3
app.get('/', (req, res) => {
res.send('Eu nunca serei chamado! T.T');
});
app.listen(3000);
Execute o código com nodejs index.js
e acesse htpp://localhost:3000
É importante entender que as variáveis req
e res
fazem parte das requisições e respostas respectivamente. Tanto é que com o req.body
conseguimos os valores vindos de um formulário e com o res.render
conseguimos renderizar uma página.
Para reforçar como funciona o fluxo de requisição no middleware veja a imagem:
Na brincadeira, iniciamos passando uma informação para a primeira pessoa de uma fila e ela para a próxima, e para isso acontecer no nosso código precisamos do next()
pois ele é o responsável por chamar o próximo middleware.
// Middleware #1
app.use((req, res, next) => {
res.locals.hello = 'Hello World';
next();
});
Ainda na primeira rota, utilizamos a variável res.locals.hello
para guardar uma string, e é essa informação que será passada para os próximos middlewares dessa rota. Observe que a primeira informação foi alterada e que a brincadeira segue com o next
.
// Middleware #2
app.get('/', (req, res) => {
return res.send(res.locals.hello);
});
Na segunda rota, resgatamos o valor inserido no primeiro middleware e usamos ele no res.send
. Quando utilizamos esse res.send
estamos montando o nosso cabeçalho e ele não pode ser reescrito. Por isso é altamente recomendado prefixar o return
como fizemos acabando com o fluxo da brincadeira sem erros.
// Middleware #3
app.get('/', (req, res) => {
res.send('Eu nunca serei chamado! T.T');
});
Como você deve estar imaginando, a terceira rota nunca será exibida pois com o return
já temos nossa páginas sendo entregue ao cliente.
Todas as rotas que chamei anteriormente são middlewares, que utilizam a mesma rota e o mesmo método (GET). É um exemplo simples e pouco utilizado, pois não usaria com total poder os middlewares. É nessa parte o Express.js se diferencia da nossa brincadeira, ele separa seus middlewares por métodos, rotas e sub-rotas.
Middlewares genéricos
Podemos fazer com que um middleware seja utilizado por vários métodos(GET, POST por exemplo) e também definirmos se será utilizado qualquer rota ou a partir de uma rota específica para suas sub-rotas. Utilizaremos o método app.use
para fazer isso.
// Middleware #1
app.use((req, res, next) => {
res.locals.hello = 'Hello World';
next();
});
// Middleware #2
app.get('/', (req, res) => {
return res.send(res.locals.hello);
});
Veja que com app.use
não utilizamos uma rota, apenas pegamos as informações que ele possui, alteramos e mandamos para o próximo. É assim que a grande maioria de middlewares externos trabalham no Express.js.
O interessante é que todas as rotas que acessarmos depois desse middleware teremos essa informação disponível para todos os métodos.
Poderíamos definir uma rota /app
que precisa de autorização para acessar o dashboard de usuário por exemplo, teríamos algo parecido:
app.use('/app', (req, res, next) => {
if (!usuariologado) {
return res.redirect();
}
next();
});
Consequentemente, todas as sub-rotas de /app
utilizarão esse middleware antes de ser executada. Isso acontecerá quando acessarmos /app/dashboard
.
Não se esqueça que os middlewares trabalham em fila, por isso você precisa utilizar os middlewares que tratam as informações antes de chamar uma rota que devolva os cabeçalhos para o cliente. Você também não consegue pegar uma informação alterada antes de passar pelo middleware propriamente dito.
É hora de dar tchau
Bom galera, é isso!!
Perceba que não é difícil quanto parece. Agora é só praticar que estarás refinado para utilizar middlewares sem medo no seu próximo App. Afinal, a prática leva a perfeição.
Ah, lembrando que nesse Post utilizei a versão mais nova do Node.js e por isso consigo utilizar as features das versões mais recentes do ECMAScript. Se você ainda não utiliza essas funcionalidades se liga nesse curso gratuito sobre JavaScript com ES6+ que preparamos para você.
Veja o projeto completo no nosso github: https://github.com/Rocketseat/blog-express-middlewares
Grande abraço.