サーバーサイドのローカライズの仕組みを考えたときに、HTTPリクエスト経由でローカライズしなきゃいけないのってエラーメッセージくらいじゃない?1と思ったのでException filterでエラーをキャッチした段階でローカライズ出来る仕組みを作りました。i18nライブラリとしてi18nextを使っています。
使い方
まずはI18nextModuleをインポート。
import { I18nextModule } from "@anchan828/nest-i18n-i18next";
@Module({
imports: [
I18nextModule.register({
fallbackLng: ["en"],
resources: {
en: {
translation: { test: "Test" },
},
jp: {
translation: { test: "テスト" },
},
},
}),
],
})
export class AppModule {}
そしてUseFiltersにI18nExceptionFilterを設定します。その後は適切な場所でi18n用に用意しているExceptionの例外をスローします。その際に、引数にキーを指定します。これで準備は終わりです。
import { I18nExceptionFilter, I18nNotFoundException } from "@anchan828/nest-i18n-i18next";
@Controller()
@UseFilters(I18nExceptionFilter)
class TestController {
@Get("error")
public i18nError(): Promise<string> {
throw new I18nNotFoundException({ key: "test" });
}
}
あとはAccept-Languageヘッダーを使って言語を指定してリクエストすれば翻訳されたエラーメッセージを取得することができます。
{
statusCode: 404,
message: "テスト",
}
またGraphQLでも使用できます。その際はI18nGqlExceptionFilterを使用します。
import { I18nGqlExceptionFilter, I18nNotFoundException } from "@anchan828/nest-i18n-i18next";
@Resolver("User")
@UseFilters(I18nGqlExceptionFilter)
export class RootUserQueryResolver {
@Query()
public async user(@Args("id") id: string): Promise<Nullable<UserEntity>> {
throw new I18nNotFoundException({ key: "test" });
}
}
こちらもAccept-Languageヘッダーを設定してリクエストすれば翻訳されたエラーメッセージを取得することができます。
{
"errors": [
{
"message": "テスト",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": ["user"]
}
]
}
Exception filter 以外で使う
このパッケージはただのラッパーなので、使用したい場所でi18nextの関数を呼び出せば使えます。
import { t } from "i18next";
t('test', {lng: "jp"}) // テスト
-
もちろんサービスによる。メールとか通知系の翻訳とかあると思いますが、それは別途対応でいいと思った。言語情報別で持たなきゃいけないだろうし。 ↩