API i18n
Đường dẫn import: @sdcorejs/nestjs/i18n
Package i18n bản địa hóa các envelope apiError của thư viện. Package cung cấp catalog tiếng Anh và tiếng Việt, resolver Accept-Language, resolver template đơn giản và global exception filter tùy chọn.
Các export
| Export | Loại | Mục đích |
|---|---|---|
MessageCatalog, Catalogs | type | Ánh xạ code -> template và language -> catalog |
II18nResolver | interface | Contract translate(code, rawLang, data?) |
ILanguageResolver | interface | Contract resolve(raw): locale |
I18N_RESOLVER, LANGUAGE_RESOLVER | value | DI token |
LanguageResolverOptions | interface | Các ngôn ngữ được hỗ trợ và fallback |
DefaultLanguageResolver | class | Parser Accept-Language có trọng số |
SimpleI18nOptions | interface | Catalog, fallback và language resolver tùy chọn |
SimpleI18nResolver | class | Tra cứu catalog và nội suy {var} |
CORE_CATALOG_EN, CORE_CATALOG_VI, CORE_CATALOGS | value | Thông báo tích hợp của thư viện |
SdI18nExceptionFilter | class | Bản địa hóa body HttpException dạng apiError |
I18nModule, I18nModuleOptions | class/type | Provider global và APP_FILTER tùy chọn |
Cấu hình module
I18nModule.forRoot({
supportedLanguages: ['en', 'vi'],
fallbackLanguage: 'en',
catalogs: {
en: { 'catalog.product.not-found': 'Product {id} was not found' },
vi: { 'catalog.product.not-found': 'Không tìm thấy sản phẩm {id}' },
},
});| Option | Mặc định | Hành vi |
|---|---|---|
catalogs | {} | Shallow-merge theo từng ngôn ngữ trên message core.* tích hợp; consumer được ưu tiên |
supportedLanguages | ['en', 'vi'] | Các mã locale cơ sở được resolver mặc định chấp nhận |
fallbackLanguage | 'en' | Locale và catalog fallback |
resolver | SimpleI18nResolver | Lớp DI tùy chỉnh triển khai II18nResolver |
useGlobalFilter | true | Đăng ký SdI18nExceptionFilter làm APP_FILTER |
SdCoreModule chỉ nối dây i18n khi có option i18n.
Phân giải ngôn ngữ
const resolver = new DefaultLanguageResolver({
supported: ['en', 'vi'],
fallback: 'en',
});
resolver.resolve('fr;q=0.4, vi-VN;q=0.9'); // 'vi'Resolver tách các tag phân cách bằng dấu phẩy, đọc trọng số q (mặc định 1), sắp xếp giảm dần, chuyển về chữ thường và bỏ region (vi-VN thành vi). Tag không xác định hoặc không hợp lệ sẽ fallback.
Contract dịch
interface II18nResolver {
translate(
code: string,
lang: string | undefined,
data?: Record<string, unknown>,
): string;
}SimpleI18nResolver tra ngôn ngữ đích, sau đó ngôn ngữ fallback, rồi trả lại stable code. Nó thay placeholder {word} từ data và giữ nguyên placeholder không khớp. Với ICU, pluralization hoặc catalog từ xa, hãy đăng ký một lớp resolver tùy chỉnh.
Hành vi exception filter
throw new NotFoundException(
apiError('catalog.product.not-found', 'Product not found', { id }),
);Khi bật filter, HTTP response trở thành:
{
"error": {
"code": "catalog.product.not-found",
"message": "Không tìm thấy sản phẩm 123",
"data": { "id": "123" }
}
}Header thô ContextService.lang được truyền vào resolver. Các validation issue được bản địa hóa riêng lẻ bằng cách dùng message làm code và params làm dữ liệu nội suy. Response không phải apiError của HttpException được giữ nguyên. Khi không có resolver, code và message mặc định được giữ nguyên.
Chỉ đặt useGlobalFilter: false khi bạn tự đăng ký SdI18nExceptionFilter hoặc có application filter duy trì cùng error contract.
Lưu ý bảo mật
- Coi nội dung catalog là phần trình bày, không phải logic phân quyền. Client phải rẽ nhánh theo
codeổn định, không bao giờ theomessageđã dịch. - Giữ dữ liệu nội suy có giới hạn và không nhạy cảm; filter giữ lại dữ liệu đó trong response.
ContextService.langlà đầu vào không tin cậy. Resolver tùy chỉnh phải chuẩn hóa nó trước khi tra cứu filesystem, network hoặc dynamic-module.
