Мультиязычность API

Добавление мультиязычности к API. Перевод сообщений валидации и доменных ошибок. Автораспознавание заголовка Accept-Language.

  • 00:00:40 - Подходы к мультиязычности
  • 00:02:52 - Тест на перевод ошибок валидации
  • 00:03:58 - Переводы для валидатора
  • 00:04:57 - Компонент Translation
  • 00:06:56 - Подключение переводчика к валидатору
  • 00:12:08 - Автоматическое переключение языков
  • 00:12:47 - Посредник TranslatorLocale
  • 00:17:25 - Парсинг Accept-Language
  • 00:20:54 - Тест TranslatorLocaleTest
  • 00:23:54 - Рефакторинг с разделением ответственностей
  • 00:25:31 - Посредник LocaleNegotiation
  • 00:29:10 - Плюсы разделения ответственностей по разным классам
  • 00:30:58 - Использование готовых посредников
  • 00:34:22 - Перевод доменных исключений
  • 00:40:50 - Публикация посредников на примере DomainExeptionHandler
Скрытый контент
Комментарии (11)
Arunas

Да, очень солидно и интересно, спасибо.

Ответить
Arunas

здесь, как понимаю, настройка языка и перевод происходит автоматически (от locale), а что если пользователь из России захочет английский текст - напр. ошибки в английском тексте?

Ответить
Дмитрий Елисеев

Язык выбирается автоматически по HTTP-заголовку Accept-Language при запросе API. Так что может либо отправить запрос без заголовка, либо со значением en

Ответить
Arunas

спасибо

Ответить
Руслан

Дмитрий, спасибо за как всегда очень содержательный и интересный урок!

Хотел узнать, будет ли затронута тема использования GraphQL для ReactJS клиента на базе текущего Slim API? Если в данном проекте это оверхед, то может Ваши критерии когда это актуально, преимущества/недостатки (н-р. легче поддерживать версионирование API, снижение количества запросов к API и др.), рекомендации использовать с Apollo-server или без и пр.

Спасибо.

Ответить
Дмитрий Елисеев

Да, поговорим про него.

Ответить
Руслан

Супер, спасибо!

Ответить
KonTuzh

Дмитрий, спасибо за такое подробное объяснение!

При последней проверке кода psalm на файле ValidationExceptionHandler начал ругаться на отсутствие интерфейса Stringable, который указан в Symfony\Component\Validator\ConstraintViolationInterface в качестве возвращаемого типа данных для метода getMessage. Насколько я понял, этот класс появится/появился в PHP8, а у нас 7.4. Так что пришлось дополнительно поставить пакет symfony/polyfill-php80

Возможно, я забегаю вперед и этот момент еще будет разбираться в будущем... у меня вопрос по локализации самого сайта: меню, статьи и другой контент страниц. Каким образом лучше это организовать в базе данных? Разные таблицы? Разделение на разные записи в одной таблице с различием по полю locale?

Ответить
Дмитрий Елисеев

Локализовать сайт не будем.

Для фронтенда можно установить react-localize-redux, добавить переводы и вызывать:

<Translate id="menu.about">About</Translate>

А для бэкенда можно переводимый контент вынести в отдельную коллекцию:

class Post {
    private Id $id;
    private string $slug;
    private Collection<Content> $contents;
    private Status $status;
}

class Content
{
    private string $lang;
    private string $title;
    private string $text;
}
Ответить
Ruslan

Не проходит psalm (commit Added domain exception translation от 17.03.2020):

ArgumentTypeCoercion - config/common/doctrine.php:45:38 - Argument 2 of Doctrine\DBAL\Types\Type::addType expects class-string<Doctrine\DBAL\Types\Type>, parent type string provided
                Type::addType($name, $class);

MixedArgumentTypeCoercion - config/common/doctrine.php:58:13 - Argument 1 of Doctrine\ORM\EntityManager::create expects Doctrine\DBAL\Connection|array<string, mixed>, parent type array<array-key, mixed> provided
            $settings['connection'],

InvalidArrayOffset - config/common/mailer.php:44:23 - Cannot create offset of type false|string, expecting array-key
            'from' => [getenv('MAILER_FROM_EMAIL') => 'Auction'],

MixedArgumentTypeCoercion - src/Auth/Entity/User/User.php:253:33 - Type mixed should be a subtype of App\Auth\Entity\User\UserNetwork
        return $this->networks->map(static function (UserNetwork $network) {

MixedAssignment - src/Auth/Entity/User/UserRepository.php:78:14 - Unable to determine the type that $user is being assigned to
        if (!$user = $this->repo->find($id->getValue())) {

Как правильно с ними поступить?

Ответить
Дмитрий Елисеев

Исправить, как мы сделали это в следующих эпизодах.

Ответить
Зарегистрируйтесь или войдите чтобы оставить комментарий

Или войти через:

Google
GitHub
Yandex
MailRu