Главная/Резолвинг/Лестница резолвинга ENУКРРУС API-справочник (ReDoc) ↗

Лестница резолвинга

Точный порядок работы /v1/resolve и что означает каждое значение match.

Резолвинг — это два поиска и лестница. Всё работает на снапшоте каталога в памяти: ни одного запроса к базе на запрос пользователя.

Шаг 1 — найти провайдера

Присланное значение нормализуется и сверяется с кодами провайдеров, затем с их алиасами. Нет совпадения — provider_not_found (404).

Шаг 2 — найти язык

Присланное значение нормализуется (см. Aliases and Normalisation) и сверяется сначала с каноническими кодами, потом с алиасами. Канонические коды регистрируются первыми и никогда не перезаписываются, так что алиас не может затенить настоящий код языка.

Если точного совпадения нет, код постепенно укорачивается:

zh-Hant-HK  →  zh-hant  →  zh-hk  →  zh

Обе оси квалификаторов присутствуют, потому что провайдеры не согласны, какая из них важна: DeepL хочет zh-Hans, Papago хочет zh-CN. Тег с неизвестным квалификатором деградирует до языка, который он уточняет, а не падает в 404: de-AT-1996 резолвится в de-AT, что видно в matched_alias.

Всё равно ничего? language_not_found (404).

Шаг 3 — лестница

Теперь, когда оба известны, по порядку:

1. exact — явная строка для этой пары

Кто-то настроил. Возвращаем её код.

{ "provider": "deepl_api", "language": "zh-CN", "code": "zh-Hans", "match": "exact" }

Если в строке is_supported: false — останавливаемся: supported: false, code: null. Пара известна как нерабочая, запрос делать не нужно.

2. variant — менее специфичный тег того же языка имеет строку

Нет строки для zh-Hant-HK, но есть для zh-TW? Берём её и называем в via_language.

{ "language": "zh-Hant-HK", "code": "zh-Hant", "match": "variant", "via_language": "zh-TW" }

3. canonical — язык без квалификатора

Базовому языку маппинг не нужен: его собственный код и есть ответ.

{ "language": "uk", "code": "uk", "match": "canonical" }

Это точно повторяет консоль

get_lang_code_by_provider_and_language начинается с if language.abbreviation: return language.abbreviation — он возвращает двухбуквенный код ещё до того, как посмотрит на провайдера. Именно поэтому консоль хранила коды только для региональных языков, и именно поэтому базовый язык без строки — норма, а не пробел.

4. Fallback policy провайдера

Достигается только для регионального языка, для которого ничего не настроено. Как выбирать — Fallback Policies.

Политика Результат match
base_language код базового языка — pt-BRpt base_language
passthrough канонический код без изменений passthrough
strict supported: false, code: null

Все провайдеры сейчас едут на base_language — это то, что консоль делает сегодня (lang_region_list.code[:2]). Почему strict не дефолт — Fallback Policies.

Как читать match на стороне вызывающего

match Уровень доверия Что делать
exact Настроено осознанно Использовать.
variant Настроено для близкого тега Использовать. Стоит закрепить, если повторяется.
canonical Нечего решать Использовать.
base_language Выведено — регион потерян Использовать, но если региональная точность критична — проверьте пару.
passthrough Выведено — не проверено против этого API Использовать и следить за ошибками провайдера.

Большинство вызывающих может вообще игнорировать match и просто отправлять code. Он для тех, кто не может.

Разобранный пример

GET /v1/resolve?provider=deepl_api&language=zh_hant_hk

  1. deepl_api совпадает с кодом провайдера.
  2. zh_hant_hk нормализуется в zh-hant-hk. Канонического совпадения нет; цепочка пробует zh-hant — это алиас zh-TW. Язык = zh-TW, matched_alias: "zh-hant".
  3. У DeepL есть явная строка для zh-TWzh-Hant.
{ "query": "zh_hant_hk", "provider": "deepl_api", "language": "zh-TW",
  "code": "zh-Hant", "supported": true, "match": "exact",
  "matched_alias": "zh-hant", "via_language": null }

Попробуйте сами

На странице Tools в админке есть живой тестер, выполняющий тот же код, — можно проверить пару, не пиша запрос.

Далее