Перевод словарей из api
Создаю клиент-серверное приложение для себя и передо мной возник вопрос: "А как же 'правильно' с архитектурной точки зрения реализовать частичный перевод json'ов".
Сервер пишу на java+spring, а клиент c#+prism(unity)+refit.
Пример текущего кода для сущности Country.
На сервере код довольно прост: Controller -> Service -> Repository.
На клиенте чуть-чуть поинтереснее:
ICountryRepository.cs
public interface ICountryRepository
{
[Get("/countries/")]
Task<IReadOnlyCollection<Country>> FindAll();
}
Посмотрел на паттерн UnitOfWork и фактически реализовал его(ну или я сделал объединение всех репозиториев в один), но уже без сохранения всех изменений.
RepositoryService.cs
public class RepositoryService : IRepositoryService
{
public ICountryRepository Country { get; }
public RepositoryService(IAuthenticationService authenticationService)
{
Country = RestService.For<ICountryRepository>(authenticationService.HttpClient);
}
}
Ну и через DI я получаю этот сервис и обращаюсь к сущностям и их методам. На данном этапе все отлично работает. Как в эту систему внедрить перевод хотя бы сущностей-словарей(таблиц-словарей) страны, национальности и.т.п
Пока в голову пришли 3 идеи:
- Перевод всех словарей хранить на сервере и уже через api'шку дергать нужный мне перевод,
- На клиенте реализовать TranslateService, который будет принимать коллекции оригинальных сущностей, а на выходе отдавать переведенные,
- Вместо RepositoryService для каждого репозитория сделать свой уникальный, где будет уже осуществляться перевод.
Пока думаю над 1 и 3, а 2 на мой взгляд попахивает чем-то нехорошим) Может у вас есть какие-либо мысли, а мой подход(ы) полностью неверные.
UPD:
Многие крупные компании не запариваются на такой мелкой детали(тот же steam, где нет перевода списка стран), но все-таки хочется)
UPD 2
Для общих таблиц-справочников сделал следующее: любой метод перед тем как отдать данные, обращается к компоненту, который возвращает настройки пользователя из текущей сессии. В них метод находит текущий язык и в зависимости от него отправляют коллекции на русском или английском.
Ответы (1 шт):
Если вы пытаетесь построить REST подобное API, то локализация это часть Content-Negotiation, то есть HTTP уже имеет средства для реализации «согласования содержимого» (механизм выбора лучшего представления для ответа, когда есть несколько представлений).
Самый изящный, на мой взгляд, способ - это использовать Accept-Language заголовок запроса. Многие HTTP клиенты передают его автоматически, к примеру если вы вызовите свое API из браузера, этот заголовок будет содержать локаль браузера.
curl */countries -X GET -H 'accept-language: ru'
Такой запрос должен вернуть список стран в русской локали.
Второй способ передать в API через query параметр:
curl */countries?lang=ru -X GET
Запрос аналогично должен вернуть список стран в русской локали.
То есть ваше серверное приложение, разбирает запросы получает от туда хедер Accept-Language или query параметр lang и возвращает список в необходимой локали, в случае отсутствия значения возвращаются данный в локали по умолчанию.
Реализация локализации на клиенте влечет за собой ряд неудобств. Главный из которых это невозможность оперативно добавлять, удалять и редактировать данные локализации. К примеру если у вас добавились новые страны, то вам необходимо будет добавить новые локали на клиент, собрать его и распространить между пользователями, вместо того чтобы добавить их один раз на сервере, который, в большинстве случаев, даже не надо останавливать.