Jose Selesan
Jose Selesan

Reputation: 718

Best way to architecture server side i18n

I'm using nestjs to create my REST API, and I got the requirement to support i18n for all the messages that the API returns (exception messages, hints, and so on) and I'm wondering what is the better way to do it with nestjs framework.

With plain express, I can get the user language from the request headers, and that can be translated to a Nestjs Middleware in order to put the language code into someware that lives in the request execution context and then using from my i18n service (I do not want to add language parameters everyware I need the user language) What do you think? Is it a propper architecture to resolve my requirement? Which is the best place to put the language for the current request?

Upvotes: 10

Views: 13840

Answers (4)

Valentine Shi
Valentine Shi

Reputation: 7848

To make an architectural decision you ask for I would think on the below first.

  1. If your API wraps a service that only does some actions (sending emails, proceesses some data, makes calculations and the like) I would only return standardizes error or hint codes and their standardized English messages.

    The translation thing should be done on a front-end application whatever it is. On its end you would be fine just using any templating engine (does not matter if it is even Node or PHP or anything else you create your front-end with) and Poedit.

    The application is responsible to know which error or hint code translates to which matching front-end UI message. And Poedit will take its work on translation with node-gettext and gettext-parser.

  2. If on the contrary your API wraps the multilanguage content (which is not your case as you describe it) than you have no choice and you have to implement the language selecting mechanism for each request. As you said the language is defined by the browser via HTTP request header.

    You have to create the application service object responsible for getting content translations (from the content repository) based on the language argument and, say, the base language content item ID you pass into it.

    FYI pay attention to REQUEST scoped injection so the service is dependent on the particular request context and treat the language setting correctly.

The i18n implementation can be anything applicable to your case.

Upvotes: 0

Willian
Willian

Reputation: 3405

I've been using Nestjs-i18n package.

It contains built-in features such as I18nService and I18nLang decorator.

Upvotes: 4

Antoine
Antoine

Reputation: 81

I don't think there is a way to get the language code in a service without passing it as a parameter. If you want to access the language code from your services, you will have to pass it as a parameter, or retrieve the language code associated to the user object from another place.

I handle translations in my app as following:

I have a Language decorator for handling the 'accept-language' header overriding by client:

export const Language = createRouteParamDecorator((data, req) => {
if (!req.body.lang) return req.getLocale();
return req.body.lang;
});

And use it like this in a controller:

@Post()
public async testLocale(@Req() req, @Language() locale) {
   return this.myService.someMethod(someParam, locale);
}

Upvotes: 1

Kamil Myśliwiec
Kamil Myśliwiec

Reputation: 9178

I'd use i18-node package https://github.com/mashpie/i18n-node, is compatible with express, and therefore there are no contradictions to use it with Nest as well. Also, I'd recommend registering a custom decorator as a wrapper around res.__ call.

Upvotes: 8

Related Questions