AdonisJs. Named Middlewares with passing props

Making life o lot easier by reducing copy-pasting logic using named Middleware

Let’s consider and example.

You want to check user ROLE (admin, user, viewer, editor, ect) in your application and in specific Routes.

Off course, you can implement this checking by inserting lines of code in each of your Controller index, show, store, update, etc functions where it needed, like:

async index ({ auth }) {
const user = await auth.getUser();
if (user.role === 'admin') {
// do something
} else {
// do something
}
}
async store ({ auth }) {
const user = await auth.getUser();
if (user.role === 'editor') {
// do something
} else {
// do something
}
}
....

But, as you can see, there will be to much copy-pasting each time you will need this checks.

There is a better solution.

Named middleware

Main difference between global and named middleware is that global middleware will be used in each request, but named middleware (auth, for example) can be used there, where it’s needed.

Route
.get(`users`, 'UserController.index')
.middleware('auth')
.formats(['json']);

And you can pass props to that middleware as well.

Creating named middleware

1. Use adonis cli command

make:middleware

adonis make:middleware RoleDetector
> Select middleware type (Use arrow keys)
For HTTP requests
For Websocket requests
For both HTTP and Websocket requests

If you choose For HTTP requests, middleware will be created only with handle function:

class SomeMiddleware {
async handle (ctx, next, schema) {
// do something
await next();
}
}

Selecting For Websocket requests will create middleware with wsHandle function, with the exactly same code.

As you understand selecting For both HTTP and Websocket requests with create middleware with both functions.

2. Registration

Next, you need to register your middleware in the /start/kernel.js file by adding path string with your custom name:

const namedMiddleware = {
...
role: 'App/Middleware/RoleDetector',
};

3. Start using it

Let create a simple console.log() functionality in our RoleDetector.js file:

And now you can start using it in your application with those Routes you needed. Let’s see an example:

Route
.resource('addresses', 'AddressController')
.middleware(new Map([
[[
'index'], ['role:admin']],
]))
.apiOnly();

Here we are saying that we want to use our created RoleDetector middleware (by name, that we defined in namedMiddleware) and passing ‘admin’ property.

Let’s see console result:

info: RoleDetector. Role: [ 'admin' ]

You can pass as many properties as you like:

.middleware(new Map([
[[
'index'], ['role:admin,custom,helloWorld']],
]))

Console result would be:

info: RoleDetector. Role: [ 'admin', 'custom', 'helloWorld' ]

Java, Spring, Node.js, AdonisJs, React.js and Flutter developer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store