Middleware
Middleware are a series of functions that are executed during an HTTP request before it reaches the route handler. Every function in the chain has the ability to end the request or forward it to the next
function.
Basic Example
The simplest way to test a middleware is to attach it to the route using the Route.middleware
method. For example:
Route
.get('/users/:id', async () => {
return 'Show user'
})
.middleware(async (ctx, next) => {
console.log(`Inside middleware ${ctx.request.url()}`)
await next()
})
Middleware classes
Writing middleware as inline functions is fine for some quick testing. However, we recommend extracting the middleware logic to its own file.
You can create a new middleware by running the following Ace command.
node ace make:middleware LogRequest
# CREATE: app/Middleware/LogRequest.ts
About middleware class
Middleware classes are stored (but not limited to) inside the app/Middleware
directory and each file represents a single middleware.
Every middleware class must implement the handle
method to handle the HTTP request and call the next
method to forward the request to the next middleware or the route handler.
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()
}
}
Also, you can terminate requests from the middleware by raising an exception or sending the response using the response.send
method.
Make sure you do NOT call the next
method when decided to end the request.
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()
}
}
Registering middleware
For the middleware to take effect, it must be registered as a global middleware or a named middleware inside the start/kernel.ts
file.
Global middleware
Global middleware are executed for all the HTTP requests in the same sequence as they are registered.
You register them as an array inside the start/kernel.ts
file, as shown below:
Server.middleware.register([
() => import('@ioc:Adonis/Core/BodyParser'),
() => import('App/Middleware/LogRequest')
])
Named middleware
Named middleware allows you to selectively apply middleware on your routes/group of routes. You begin by registering them with a unique name and later reference it on the route by that name.
Server.middleware.registerNamed({
auth: () => import('App/Middleware/Auth')
})
Now, you can attach the auth
middleware to a route as shown in the following example.
Route
.get('dashboard', 'DashboardController.index')
.middleware('auth') // 👈
The middleware can be applied to one or multiple actions for resource routes. Learn more about applying middleware to resourceful routes .
You can also define multiple middleware on a route by passing them as an array or calling the middleware method multiple times.
Route
.get('dashboard', 'DashboardController.index')
.middleware(['auth', 'acl', 'throttle'])
Route
.get('dashboard', 'DashboardController.index')
.middleware('auth')
.middleware('acl')
.middleware('throttle')
Passing config to named middleware
Named middleware can also accept runtime config through the handle
method as the third argument. For example:
export default class Auth {
public async handle(
{ request, response }: HttpContextContract,
next: () => Promise<void>,
guards?: string[]
) {
await next()
}
}
In the above example, the Auth middleware accepts an optional guards
array. The user of the middleware can pass the guards as follows:
Route
.get('dashboard', 'DashboardController.index')
.middleware('auth:web,api')
FAQs
How to disable middleware on a given HTTP request?
You cannot disable middleware for a given HTTP request. However, the middleware can accept the runtime config to ignore certain requests.
A great example of this is the bodyparser middleware. It ignores all the requests not matching the whitelisted
methods inside the config/bodyparser.ts
file.
Are middleware executed on requests with no routes?
AdonisJS does not execute the middleware chain, if there is no registered route for the current HTTP request.