javascriptnode.jsbackendadonis.jslucid

AdonisJS - How to return validation messages according to the locale of Antl Provider


I'm applying internationalization to my API and I'm having some issues related to Antl and validation messages.

With standard response messages, I'm returning according to the locale set by the user. I created a route to switch locales and set to a cookie and a global middleware to get the locale from the cookie and then I just return the message stored in the locale resources.

Global Middleware:

class Locale {
  async handle ({ request, antl }, next) {
    const lang = request.cookie('lang')

    if (lang) {
      antl.switchLocale(lang)
    }

    await next()
  }
}

Route:

Route.get('/switch/:lang', ({ params, antl, request, response }) => {
  // Getting the current available locales
  const locales = antl.availableLocales()

  try {
    // Saving into cookies
    if (locales.indexOf(params.lang) > -1) {
      response.cookie('lang', params.lang, { path: '/' })
    }

    return response.status(200).send({ message: 'Locale changed succesfully' })
  } catch (err) {
    return response.status(err.status).send({ error: 'Something went wrong while trying to switch locales', data: { message: err.message || 'Error message not found', name: err.name } })
  }
})

But i have two files with validation messages:
PT - https://github.com/LauraBeatris/xpack-adonis-api/blob/develop/resources/locales/pt/validation.json
EN - https://github.com/LauraBeatris/xpack-adonis-api/blob/develop/resources/locales/en/validation.json

And I want to return the validation messages according to the current locale set by the user, but the problem is that the get method of the validator class doesn't have access to the antl context object like the others middlewares.

Messages method of the validator:

    get messages () {
    return Antl.list('validation')
  }

But, when I changed the locale with the antl object provided by the middleware context, it doesn't change in the global provider, so the validation messages will always return with the default locale, instead of the one set by the user in the middleware. I want to integrate the locale switch route with that antl global provider, so I'll be able to return Portuguese validation messages, for example.

That's the repo of my project: https://github.com/LauraBeatris/xpack-adonis-api


Solution

  • To use the Antl object in the get messages() method of the validator, you need to use this.ctx.antl. Like :

    var antl = this.ctx.antl;
    ...
    antl.formatMessage(...)
    


    Adonis does not store the language used by Antl between queries. All routes must have the middleware that applies the language (the one you made). Example :

    Route.get('/user', 'UserController.Get').middleware(['Locale']); // Use cookie language
    
    Route.get('/user', 'UserController.Get'); // Use default language
    

    If you want all routes to have this middleware, you have to add it in start/kernel.js. : https://adonisjs.com/docs/4.1/middleware#_global_middleware

    Don't hesitate if you need more information :)