데이터베이스에 다국어 값을 저장해야 할 때, name, name_ko, name_en처럼 locale별 컬럼을 사용할 수 있습니다. Sonamu는 localizedColumn() 함수로 현재 locale에 맞는 값을 자동으로 선택합니다.
localizedColumn 함수
import { localizedColumn } from "../i18n/sd.generated";
const tag = {
id: 1,
name: "default",
name_ko: "태그",
name_en: "Tag",
};
// Context locale이 "ko"일 때
localizedColumn(tag, "name") // "태그"
// Context locale이 "en"일 때
localizedColumn(tag, "name") // "Tag"
// Context locale이 "ja"일 때 (지원하지 않는 locale)
localizedColumn(tag, "name") // "default" (기본 컬럼으로 폴백)
우선순위
localizedColumn()은 다음 순서로 값을 찾습니다:
| 현재 locale | 우선순위 |
|---|
ko | name_ko → name → name_en |
en | name_en → name → name_ko |
빈 문자열("")이나 null은 건너뛰고 다음 우선순위를 확인합니다.
Entity 정의
다국어 컬럼을 가진 Entity 예시:
{
"id": "Tag",
"table": "tags",
"props": [
{ "name": "id", "type": "integer" },
{ "name": "name", "type": "string", "length": 100, "desc": "기본 이름" },
{ "name": "name_ko", "type": "string", "length": 100, "nullable": true, "desc": "한국어 이름" },
{ "name": "name_en", "type": "string", "length": 100, "nullable": true, "desc": "영어 이름" }
]
}
Model에서 사용
Subset에서 가공
Subset의 enhancer에서 localizedColumn을 사용하여 클라이언트에 단일 name 필드만 전달할 수 있습니다:
import { localizedColumn } from "../i18n/sd.generated";
class TagModelClass extends BaseModelClass {
async findMany<T extends TagSubsetKey>(subset: T, params: TagListParams) {
// ...
const enhancers = this.createEnhancers({
A: (row) => ({
...row,
// locale에 맞는 이름으로 대체
displayName: localizedColumn(row, "name"),
}),
});
return this.executeSubsetQuery({ subset, qb, params, enhancers });
}
}
API 응답에서 사용
@api({ httpMethod: "GET" })
async getTagOptions(): Promise<{ id: number; label: string }[]> {
const tags = await this.findMany("A", { num: 100 });
return tags.rows.map(tag => ({
id: tag.id,
label: localizedColumn(tag, "name") ?? tag.name,
}));
}
프론트엔드에서 사용
프론트엔드에서도 동일한 함수를 사용할 수 있습니다 (web의 sd.generated.ts에서 export):
import { localizedColumn } from "@/i18n/sd.generated";
function TagBadge({ tag }: { tag: Tag }) {
return (
<span className="badge">
{localizedColumn(tag, "name")}
</span>
);
}
컬럼 네이밍 패턴
| 기본 컬럼 | locale 컬럼 | 설명 |
|---|
name | name_ko, name_en | 이름 |
title | title_ko, title_en | 제목 |
description | description_ko, description_en | 설명 |
content | content_ko, content_en | 내용 |
컬럼 이름은 반드시 {기본컬럼}_{locale} 형식이어야 합니다. 예: name_ko, title_en
주의사항
localizedColumn은 단순히 컬럼 값을 선택하는 함수입니다. 쿼리 최적화(필요한 컬럼만 SELECT)는 별도로 처리해야 합니다.
- 모든 locale 컬럼이
null이고 기본 컬럼도 빈 값이면 undefined를 반환합니다.
- Context에 locale이 설정되지 않으면
defaultLocale을 사용합니다.