Middleware
Middleware é uma série de funções que são executadas durante uma solicitação HTTP antes que ela chegue ao manipulador de rota. Cada função na cadeia tem a capacidade de encerrar a solicitação ou encaminhá-la para a função next
.
Exemplo básico
A maneira mais simples de testar um middleware é anexá-lo à rota usando o método Route.middleware
. Por exemplo:
Route
.get('/users/:id', async () => {
return 'Show user'
})
.middleware(async (ctx, next) => {
console.log(`Inside middleware ${ctx.request.url()}`)
await next()
})
Classes de middleware
Escrever middleware como funções inline é bom para alguns testes rápidos. No entanto, recomendamos extrair a lógica do middleware para seu próprio arquivo.
Você pode criar um novo middleware executando o seguinte comando Ace.
node ace make:middleware LogRequest
# CREATE: app/Middleware/LogRequest.ts
Sobre a classe middleware
As classes middleware são armazenadas (mas não limitadas a) dentro do diretório app/Middleware
e cada arquivo representa um único middleware.
Toda classe middleware deve implementar o método handle
para manipular a solicitação HTTP e chamar o método next
para encaminhar a solicitação para o próximo middleware ou o manipulador de rota.
// app/Middleware/LogRequest.ts
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class LogRequest {
public async handle(
{ request }: HttpContextContract,
next: () => Promise<void>
) {
console.log(`-> ${request.method()}: ${request.url()}`)
await next()
}
}
Além disso, você pode encerrar solicitações do middleware gerando uma exceção ou enviando a resposta usando o método response.send
.
NOTA
Certifique-se de NÃO chamar o método next
quando decidir encerrar a solicitação.
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class Auth {
public async handle(
{ request, response }: HttpContextContract,
next: () => Promise<void>
) {
if (notAuthenticated) {
response.unauthorized({ error: 'Must be logged in' })
return
}
await next()
}
}
Registrando middleware
Para que o middleware entre em vigor, ele deve ser registrado como um middleware global ou um middleware nomeado dentro do arquivo start/kernel.ts
.
Middleware global
Middleware global é executado para todas as solicitações HTTP na mesma sequência em que são registradas.
Você os registra como uma matriz dentro do arquivo start/kernel.ts
, conforme mostrado abaixo:
// start/kernel.ts
Server.middleware.register([
() => import('@ioc:Adonis/Core/BodyParser'),
() => import('App/Middleware/LogRequest')
])
Middleware nomeado
O middleware nomeado permite que você aplique middleware seletivamente em suas rotas/grupo de rotas. Você começa registrando-os com um nome exclusivo e depois faz referência a ele na rota por esse nome.
// start/kernel.ts
Server.middleware.registerNamed({
auth: () => import('App/Middleware/Auth')
})
Agora, você pode anexar o middleware auth
a uma rota, conforme mostrado no exemplo a seguir.
Route
.get('dashboard', 'DashboardController.index')
.middleware('auth') // 👈
O middleware pode ser aplicado a uma ou várias ações para rotas de recursos. Saiba mais sobre aplicação de middleware a rotas com recursos.
Você também pode definir vários middlewares em uma rota passando-os como uma matriz ou chamando o método do middleware várias vezes.
Route
.get('dashboard', 'DashboardController.index')
.middleware(['auth', 'acl', 'throttle'])
Route
.get('dashboard', 'DashboardController.index')
.middleware('auth')
.middleware('acl')
.middleware('throttle')
Passando configuração para middleware nomeado
O middleware nomeado também pode aceitar configuração de tempo de execução por meio do método handle
como o terceiro argumento. Por exemplo:
export default class Auth {
public async handle(
{ request, response }: HttpContextContract,
next: () => Promise<void>,
guards?: string[]
) {
await next()
}
}
No exemplo acima, o middleware Auth aceita uma matriz opcional guards
. O usuário do middleware pode passar os guards da seguinte forma:
Route
.get('dashboard', 'DashboardController.index')
.middleware('auth:web,api')
FAQs
Como desabilitar middleware em uma determinada solicitação HTTP?
Você não pode desabilitar middleware para uma determinada solicitação HTTP. No entanto, o middleware pode aceitar a configuração de tempo de execução para ignorar certas solicitações.
Um ótimo exemplo disso é o middleware bodyparser. Ele ignora todas as solicitações que não correspondem aos métodos da lista de permissões dentro do arquivo config/bodyparser.ts
.
O middleware é executado em solicitações sem rotas?
O AdonisJS não executa a cadeia de middleware se não houver uma rota registrada para a solicitação HTTP atual.