다국어를 제공하는 방법으로는 크게 3가지를 생각해 볼 수 있다.

 

1. 서버에서 json을 받아서 사용하기

2. 클라이언트에서 json을 하드코딩하기

3. 웹 문서 사이트 API 사용하기

 

서버에서 JSON 가져오기

서버로부터 JSON 형식으로 데이터를 받아서 클라이언트에서 적용만 하는 방식이다. 서버에서 데이터가 관리되기 때문에 내용에 변경사항이 생겨도 클라이언트에서 따로 수정이 필요하지 않으며 여러 플랫폼에서 동일한 데이터를 사용할 수 있다.

 

언어별 스키마 속성 추가

Monster라는 테이블이 있을 때 다음과 같이 정의한다.

Monster Table
{
	'monsterId' : '1',
    'monsterNameKor' : '박코딩',
    'monsterNameEng' : 'Coding Bak',
}

 

하나의 테이블에서 지원할 언어만큼 속성을 추가해서 만든다. 단순한 구조로 데이터가 추가되어도 DB가 크게 복잡해지지 않기 때문에 확장성이나 유지, 보수 측면에서 유리하다. 다만 사용하는 데 있어서 클라이언트에서는 적용할 때 서비스할 언어에 맞춰 Kor, Eng를 구분해서 접근하거나 또는 API 호출에서 구분해서 데이터를 받을 수 있도록 서버단에서 작업을 해줄 필요가 있다.

 

언어별 테이블 분리

제공할 언어마다 테이블을 따로 분리하는 구조이다.

Moster_Kor Table
{
	'id' : '1',
    'name' : '박코딩'
}

Monster_Eng Table
{
	'id' : '1',
    'name' : 'Coding Bak'
}

 

클라이언트에서는 별도로 처리할 필요 없이 name으로 접근해서 사용할 수 있어 편리하지만 서버 입장에서는 DB의 구조가 복잡해지고 지원할 언어의 수만큼 테이블이 배로 늘어나기 때문에 유지 보수에 불리하다.

 

다중 언어 전용 테이블 구조

다국어가 적용될 모든 데이터에 대한 정보를 모아두고 사용할 방식에 맞게 데이터를 정리해서 보낸다.

Monster Table
{
	'monsterId' : '1',
    'monsterName_tId' : '1'
}

Language Table
{
	'tId' : '1',
    'eng' : 'Coding Bak',
    'kor' : '박코딩',
}

 

 

번역이 필요한 정보들을 하나의 테이블에 묶고 별도의 키값을 통해서 데이터를 연동시켜 사용하는 방식이다. 한 곳에서 일괄적으로 정보들을 관리할 수 있기 때문에 데이터가 수정되거나 추가될 때 쉽게 처리가 가능하다. 하지만 데이터를 연관 짓고 필요한 정보만 묶어서 보내야 하기 때문에 DB구조와 쿼리문이 복잡해질 수 있다.

 

서버에서 언어 데이터를 관리하는 방식에는 여러 방법들이 있지만 서버에 요청하고 응답을 기다려야 하기 때문에 데이터량과 위치에 따라서 지연시간에 대한 문제가 발생할 수 있다. 서버에서 보낼 데이터량이나 서비스할 지역이 여러 곳이라면 각 지역별 인터넷 환경과 서버로부터 거리 또한 고려해서 대응이 필요하다.

 

이런 문제를 해결하기 위한 방법들도 존재한다.

 

Edge Computing

사용자 또는 데이터 소소의 물리적인 위치나 그 근처에서 컴퓨팅을 수행하는 것으로 사용자가 단말 장치와 가까운 위치에서 컴퓨팅 서비스를 처리하면 더 빠르고 안정적인 서비스를 제공받을 수 있는 여러 위치에서 공통의 리소스 풀을 사용하여 데이터 연산 및 처리를 분산시키는 방법이다.

 

AWS Lambda, Cloudflare Workers 등에서 서비스를 사용할 수 있다.

 

SSG

Server Side Generation 또는 Static Site Generation

Next.js 같은 메타 프레임워크에서 사용할 수 있는 방식으로 빌듯이 데이터를 받아서 미리 언어별로 페이지를 분기처리하는 방식이다.  빌드할 때 서버로부터 요청을 보내고 데이터를 받아와서 파일들을 미리 생성해 놓기 때문에 지연시간이 발생하지 않게 하는 방식이다.

 

클라이언트에서 관리

언어 데이터를 클라이언트단에서 관리하는 방식이다. 별도의 서버 요청이 필요 없기 때문에 요청하고 응답을 대기하는 시간이 없다. 하지만 정보가 변경될 때마다 클라이언트에서 수정이 필요할 수 있다.

 

클라이언트 내부에서 하드코딩으로 직접 언어 데이터를 정리해서 사용하는 경우 데이터 수정 시 클라이언트의 수정이 필요하고 다른 플랫폼의 클라이언트도 있는 경우 모두 동일하게 수정해서 데이터를 일치시켜야 하는 번거로움이 있다.

 

일반적으로 json 형식으로 데이터 파일을 만들고 클라이언트에서는 파일을 로드하고 코드상에서 값들을 가져다 쓰는 방식을 사용한다. 

 

별도의 json 다국어 데이터 파일
{
  "en": {
    "greeting": "Hello!",
    "buttonText": "Submit"
  },
  "ko": {
    "greeting": "안녕하세요!",
    "buttonText": "제출"
  },
  "fr": {
    "greeting": "Bonjour!",
    "buttonText": "Soumettre"
  }
}
using System;
using System.IO;
using Newtonsoft.Json.Linq;

public class Program
{
    public static void Main()
    {
        // JSON 파일 경로
        string jsonFilePath = "path/to/your/json/file.json";

        // JSON 파일 로드
        string jsonContent = File.ReadAllText(jsonFilePath);

        // JSON 파싱
        JObject jsonData = JObject.Parse(jsonContent);

        // 사용자 언어 설정 (예: "en", "ko", "fr")
        string userLanguage = "en";

        // 다국어 데이터 가져오기
        string greeting = jsonData[userLanguage]["greeting"].ToString();
        string buttonText = jsonData[userLanguage]["buttonText"].ToString();

        // 다국어 데이터 사용 예시
        Console.WriteLine(greeting);       // 인사말 출력
        Console.WriteLine(buttonText);     // 버튼 텍스트 출력
    }
}

파일을 별도로 두고 클라이언트에서는 파일을 로드하고 데이터를 가공해서 사용하게 된다. 이때 파일 위치를 번들처럼 외부에 두고 사용하여 언어 정보만 변경이 된 경우에는 해당 파일만 수정해 주면 클라이언트상에서 수정 없이 작업이 가능하다.

 

문서 관리 서비스 사용

여기서 문서 관리 서비스란 구글 스프레드시트 처럼 제공되는 서비스를 말한다. 직관적인 형식으로 데이터를 관리할 수 있으며 여러 클라이언트에서 동일한 데이터를 사용할 수 있다. 하지만 접근하기 위해서는 API의 호출이 필요하고 이 과정에서 서버에 요청이 필요하기 때문에 지연시간이 발생할 수밖에 없으며 서비스마다 지원되는 API에 제한이 있다.

 

using Google.Apis.Auth.OAuth2;
using Google.Apis.Sheets.v4;
using Google.Apis.Sheets.v4.Data;
using System;
using System.Collections.Generic;
using System.IO;

public class Program
{
    static readonly string spreadsheetId = "your-spreadsheet-id";
    static readonly string credentialsFilePath = "path/to/your/credentials.json";

    public static void Main()
    {
        // 인증 정보 로드
        GoogleCredential credential;
        using (var stream = new FileStream(credentialsFilePath, FileMode.Open, FileAccess.Read))
        {
            credential = GoogleCredential.FromStream(stream)
                .CreateScoped(SheetsService.Scope.Spreadsheets);
        }

        // SheetsService 생성
        var serviceInitializer = new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = "Your Application Name"
        };
        var sheetsService = new SheetsService(serviceInitializer);

        // 데이터 가져오기
        IList<IList<object>> values = GetSpreadsheetValues(sheetsService, spreadsheetId, "Sheet1");

        // 가져온 데이터 출력
        if (values != null && values.Count > 0)
        {
            foreach (var row in values)
            {
                foreach (var cell in row)
                {
                    Console.Write(cell + "\t");
                }
                Console.WriteLine();
            }
        }
        else
        {
            Console.WriteLine("No data found.");
        }
    }

    public static IList<IList<object>> GetSpreadsheetValues(SheetsService sheetsService, string spreadsheetId, string sheetName)
    {
        string range = $"{sheetName}!A1:Z";
        SpreadsheetsResource.ValuesResource.GetRequest request =
            sheetsService.Spreadsheets.Values.Get(spreadsheetId, range);

        ValueRange response = request.Execute();
        IList<IList<object>> values = response.Values;

        return values;
    }
}

 

다양한 방법들로 다국어 데이터를 관리할 수 있는데 이 중 장단점들을 고려하여 프로젝트의 성격 및 특징에 알맞은 방식을 선택하는 것이 중요하다. 

728x90
반응형

'Memo' 카테고리의 다른 글

C# Class 크기 확인  (0) 2023.02.06

+ Recent posts