oque-e-middleware-como-usar-para-que-serve-nodejs-express

Se você começou a ‘brincar’ com ExpressJs à pouco tempo, com certeza já esbarrou com a expressão Middleware.

Oque é MiddleWare? Para que serve? Como faço um? Onde posso usar?

Middleware é uma função com acesso ao objeto de requisição (req), de resposta (res), e ao próximo middleware no ciclo de requisição-resposta de uma aplicação Express.

A palavra ‘middleware’ significa, mais ou menos, ‘coisa para usar entre/no meio de duas coisas’.

Vamos brincar?

Preparei uma pequena aplicação pra testarmos o uso de middlewear. Você precisa ter apenas o NodeJs instalado, e seguir os passos abaixo. Node que sempre vai ter o nome do arquivo no começo da caixinha de código.

O código final do exemplo está disponível neste repositório do github, mas recomendo seguir o passo-a-passo.

Ok, vamos lá. Primeiro, inicie uma aplicação com node e express, pode usar este package.json (crie uma pasta, um arquivo com o nome package.json , com o conteúdo abaixo):

[package.json ]
1
2
3
4
5
6
7
8
9
{
"name": "usando-middleware",
"version": "1.0.0",
"main": "server.js",
"dependencies": {
"body-parser": "^1.11.0",
"express": "^4.11.2"
}
}

Agora instale as dependências com, navegando até sua pasta pelo terminal e rodando…

1
npm install

Estrutura Básica

Crie um arquivo server.js na mesma pasta do package.json.

[server.js]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var express = require('express')
, app = express()
, bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var port = process.env.PORT || 8080;
var router = express.Router();
/* Vamos colocar nosso Middleware aqui, depois */
app.use('/', router);
router.route('/teste')
.get(function(req, res){
res.json({message: "teste ok!!"});
});
app.listen(port);
console.log('conectado a porta ' + port);

Agora execute, com:

1
node server

Acessando http://localhost:8080/teste, você deve ver o retorno.
Essa é nossa aplicação básica, com a rota /teste usando o verbo .get()

Criando seu primeiro Middleware:

Agora, vamos criar o Middleware. Nada mais é do que um função com 3 párâmetros: function(req, res, next){}. Vamos criar em uma variável para ficar fácil de chamar depois.

Insira no server.js:

[server.js]
1
2
3
4
5
6
7
(...)
/* Vamos colocar nosso Middleware aqui, depois */
var noMeio = function(req, res, next){
console.log('Algo acontecendo: MIDLEWARE')
next();
};
(...)

Se ligue no next(). Note que ele é o terceiro parâmetro da função. Faz muito sentido: ‘faça isso, isso e isso, e vá pra próxima( )’.

Como evitar (travar) o carregamento da próxima função/rota?

Se você quiser travar o carregamento, basta não chamar o next.

Isso é útil, por exemplo, pra bloquear acesso. Por exemplo:

Para testar se o usuário está adimplente, antes de exibir conteúdo, basta utilizar o middleware nas rotas protegidas, puxar o req.user e conferir no DB quando foi o último pagamento.

Se estiver em dia, chamo o next(), senão: res.json({error: 'usuário inadimplente.'}), pra isso, basta saber como…

Como utilizar Middleware em rotas do ExpressJS

Para utilizar o middleware em uma rota, basta inserir ele como o primeiro parâmetro da sua função verbo(), ou seja: get(), post(), etc. A ação da rota vem como segundo parâmetro, edite o server.js como no trecho abaixo e confira:

[server.js][Edite a rota, inserindo o Middleware como primeiro parâmetro]
1
2
3
4
5
6
(...)
router.route('/teste')
.get(noMeio, function(req, res){
res.json({message: "teste ok!!"});
});
(...)

Note que inserimos a variável noMeio, que contém nosso Midware, como primeiro parâmetro do verbo .get().

Agora, execute node server novamente. Acesse http://localhost:8080/teste**. Viu, no console??

Um exemplo de uso de Middleware mais maneiro

Pra sentir um pouco mais das possibilidades, vamos editar nosso middleware para fazer algo mais útil, travar requisições de quem não tiver a senha.

[server.js][Altere o middleware noMeio]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
(...)
/* Vamos colocar nosso Middleware aqui, depois */
var noMeio = function(req, res, next){
var senha = req.query.senha || '';
if(senha == 'senhasecreta'){
next();
} else {
res.status(401).json({
aviso: 'Parado aí, meliante!',
message: 'Você não possui a senha, não pode entrar.'
})
}
};
(...)

Note que o Middleware recebe tudo que foi enviado pelo objeto req, inclusive os parâmetros de url.

Quando dizemos req.query.senha, estamos referenciando o parâmetro de url ?senha

Acesse http://localhost:8080/teste. Viu?

Agora adicione ?senha=senhasecreta, ou seja: http://localhost:8080/teste?senha=senhasecreta

Háaaa! Que legal :D

Lembrando que se você autenticar sua aplicação usando este método, você merece ser hackeado. Isso é só um exemplo, o ideal seria encriptar a senha ou utilizar Json Web Token.

O código do exemplo está disponível neste repositório do github

Tipos de Middleware

Viu, é importante lembrar que usar middleware para interceptar rotas não é a única forma, existem as seguintes maneiras de utiliza-los:

  • Nível Aplicação
  • Nível Router
  • Middleware Nativo
  • Middleware de terceiros

Middleware Nível Aplicação:

[ Midleware nível aplicação ] [Será executado em toda requisição ]
1
2
3
4
app.use(function (req, res, next) {
console.log('Hórário:', Date.now());
next();
});

Middleware de nível aplicação é executado em todas as requisições.
No exemplo acima, poderíamos implementar um bloqueio por horário, que estaria disponível em todas as rotas, automaticamente.

Nível Router

É o exemplo principal deste post, onde o middleware é executado antes de carregar a resposta das rotas. Para isso, ele é declarado no verbo.

Middleware Nativo e de Terceiros

Na listagem até risquei middleware Nativo. Fiz isso pois o Express não tem mais isso. Os módulos agora são todos de terceiros, como o body-parser, por exemplo - que antes vinha nativo.

Aliás, a maioria das coisas do express é feito por via de middlewares, dos parsers até o router. Aliás, segundo a própria documentação do Express.js:

Uma aplicação Express é essencialmente uma série de chamadas de Middleware.


Conclusão:

Middlewares são funções intermediárias e reaproveitáveis, inseridas no meio da requisição e da resposta.

Para criar um middleware basta inserir uma função com 3 parametros, sendo o primeiro o objeto da requisição, o segundo o objeto de resposta e o terceiro o callback para continuar o fluxo: function(req, res, next){}

Eles podem ser à nível APP ou nível de Rotas.

Viu como é fácil?
Eaí, tem alguma dica, ou ponto que esqueci de mencionar? Poste nos comentários!