Overview
Funções de middleware são funções que têm acesso ao objecto pedido (req
), o objecto de resposta (res
), e a função next
no ciclo de resposta de solicitação da aplicação. A função next
é uma função no router Express que, quando invocada, executa o middleware que sucede ao middleware actual.
Funções de middleware podem executar as seguintes tarefas:
- Executar qualquer código.
- Fazer alterações ao pedido e aos objectos de resposta.
- Fim do ciclo de resposta ao pedido.
li>Chamar o próximo middleware na pilha.
Se a função middleware actual não terminar o ciclo de resposta ao pedido, deve chamar next()
para passar o controlo para a próxima função middleware. Caso contrário, o pedido será deixado pendurado.
A figura seguinte mostra os elementos de uma função de middleware chamada:
métodoHTTP ao qual se aplica a função de middleware.
Caminho (rota) ao qual se aplica a função middleware.
A função middleware.
Argumento de retorno para a função middleware, chamado “next” por convenção.
Disc>Disc>Disc>Disc>HTTP argumento de resposta à função de middleware, chamado “res” por convenção.
Disc>Disc>HTTP argumento de pedido à função de middleware, chamado “req” por convenção.
|
Começar com o Express 5, funções de middleware que retornam uma promessa chamarão next(value)
quando rejeitarem ou atirarem um erro. next
será chamado com o valor rejeitado ou o Erro lançado.
Exemplo
Aqui está um exemplo de uma aplicação simples “Hello World” Express.O resto deste artigo irá definir e adicionar três funções de middleware à aplicação:uma chamada myLogger
que imprime uma simples mensagem de registo, outra chamada requestTime
que exibe o carimbo da hora do pedido HTTP, e outra chamada validateCookies
que valida os cookies recebidos.
var express = require('express')var app = express()app.get('/', function (req, res) { res.send('Hello World!')})app.listen(3000)
Função middleware myLogger
Aqui está um exemplo simples de uma função middleware chamada “myLogger”. Esta função apenas imprime “LOGGED” quando um pedido para a aplicação passa por ela. A função de middleware é atribuída a uma variável chamada myLogger
.
Nota a chamada acima para next()
. A chamada a esta função invoca a próxima função middleware no app.The next()
function is not a part of the Node.js or Express API, mas é o terceiro argumento que é passado para a função middleware. A função next()
poderia ser nomeada qualquer coisa, mas por convenção é sempre nomeada “next”.Para evitar confusão, usar sempre esta convenção.
Para carregar a função middleware, chamar app.use()
, especificando a função middleware.Por exemplo, o seguinte código carrega o myLogger
função middleware antes da rota para o caminho raiz (/).
var express = require('express')var app = express()var myLogger = function (req, res, next) { console.log('LOGGED') next()}app.use(myLogger)app.get('/', function (req, res) { res.send('Hello World!')})app.listen(3000)
Sempre que a aplicação recebe um pedido, imprime a mensagem “LOGGED” para o terminal.
A ordem de carregamento do middleware é importante: as funções de middleware que são carregadas primeiro também são executadas primeiro.
Se myLogger
for carregado após a rota para o caminho de raiz, o pedido nunca o atinge e a aplicação não imprime “LOGGED”, porque o manipulador da rota do caminho de raiz termina o ciclo de resposta do pedido.
A função middleware myLogger
simplesmente imprime uma mensagem, depois passa o pedido para a próxima função middleware na pilha chamando a função next()
.
Middleware function requestTime
Next, vamos criar uma função de middleware chamada “requestTime” e adicionar uma propriedade chamada requestTime
ao objecto de pedido.
var requestTime = function (req, res, next) { req.requestTime = Date.now() next()}
O aplicativo agora usa a função requestTime
middleware. Além disso, a função callback da rota do caminho da raiz utiliza a propriedade que a função middleware adiciona a req
(o objecto de pedido).
var express = require('express')var app = express()var requestTime = function (req, res, next) { req.requestTime = Date.now() next()}app.use(requestTime)app.get('/', function (req, res) { var responseText = 'Hello World!<br>' responseText += '<small>Requested at: ' + req.requestTime + '</small>' res.send(responseText)})app.listen(3000)
Quando faz um pedido à raiz da aplicação, a aplicação exibe agora o carimbo temporal do seu pedido no browser.
Função de middleware validarCookies
Finalmente, vamos criar uma função de middleware que valida os cookies recebidos e envia uma resposta de 400 se os cookies forem inválidos.
Aqui está uma função de exemplo que valida os cookies com um serviço externo assimétrico.
async function cookieValidator (cookies) { try { await externallyValidateCookie(cookies.testCookie) } catch { throw new Error('Invalid cookies') }}
Aqui usamos a função cookie-parser
middleware para analisar os cookies recebidos no objecto req
e passá-los à nossa função cookieValidator
. O validateCookies
middleware retorna uma promessa de que ao ser rejeitado irá automaticamente accionar o nosso manipulador de erros.
var express = require('express')var cookieParser = require('cookie-parser')var cookieValidator = require('./cookieValidator')var app = express()async function validateCookies (req, res, next) { await cookieValidator(req.cookies) next()}app.use(cookieParser())app.use(validateCookies)// error handlerapp.use(function (err, req, res, next) { res.status(400).send(err.message)})app.listen(3000)
Nota como next()
é chamado após await cookieValidator(req.cookies)
. Isto assegura que se cookieValidator
resolver, o próximo middleware na pilha será chamado. Se passar qualquer coisa à função next()
(excepto a string 'route'
ou 'router'
), a Express considera o pedido actual como sendo um erro e salta qualquer resto de funções de encaminhamento e middleware não relacionadas com o manuseamento de erros.
Porque tem acesso ao objecto de pedido, ao objecto de resposta, à próxima função de middleware na pilha, e a todo o Node.js API, as possibilidades com funções de middleware são infinitas.
Para mais informações sobre o middleware Express, ver: Usando o middleware Express.
Middleware configurável
Se precisar que o seu middleware seja configurável, exporte uma função que aceite um objecto de opções ou outros parâmetros, que, depois, devolve a implementação do middleware com base nos parâmetros de entrada.
Arquivo: my-middleware.js
module.exports = function (options) { return function (req, res, next) { // Implement the middleware function based on the options object next() }}
O middleware pode agora ser usado como se mostra abaixo.
var mw = require('./my-middleware.js')app.use(mw({ option1: '1', option2: '2' }))
Refer a cookie-session e compressão para exemplos de middleware configurável.