АналитикаСистемный анализСистемный аналитик по интеграциям

Внешний API начал добавлять новые поля в ответы. Как потребителю пережить это изменение без внепланового ре...

Внешний API начал добавлять новые поля в ответы. Как потребителю пережить это изменение без внепланового релиза?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

Потребитель должен применять принцип толерантного чтения: игнорировать неизвестные необязательные поля, но строго проверять известные обязательные поля и их типы. Тогда добавление данных поставщиком не ломает старую версию клиента.

Это не означает, что можно принимать любую структуру без проверок. Неизвестные поля безопасно пропускать только там, где контракт допускает расширение и они не меняют смысл уже известных данных.

Исторический контекст

В распределённых системах поставщик API и его потребители обычно развиваются независимо. Поэтому изменение формата ответа не может предполагать одновременный релиз всех клиентов.

Добавление новых полей — распространённый способ обратно совместимо расширить контракт. Подход с толерантным чтением возник как практическое решение проблемы, при которой старые клиенты должны продолжать работать с более новой версией ответа.

Постановка проблемы

Предположим, старый клиент знает поля id, status и total, а поставщик добавил поле discount. Если клиент считает любую неизвестную часть ответа ошибкой, обычное расширение контракта приведёт к сбоям без изменения смысла старых данных.

Обратная крайность также опасна: если клиент молча принимает отсутствующие поля, неверные типы или неожиданные значения перечислений, ошибка поставщика может превратиться в неправильные расчёты или некорректное бизнес-решение.

Подробное решение

Контракт потребителя следует разделить на несколько категорий:

  • известные обязательные поля — должны присутствовать и иметь допустимый тип;
  • известные необязательные поля — могут отсутствовать, для них задаётся явное поведение по умолчанию;
  • неизвестные поля — игнорируются, если они не влияют на интерпретацию известных данных;
  • значения перечислений — требуют отдельной политики, потому что новое значение может изменить бизнес-смысл, даже если структура ответа не изменилась.

При обработке ответа полезно валидировать структуру на границе системы, а затем передавать во внутреннюю модель только поддерживаемые поля. Это изолирует внутреннюю модель от случайных изменений внешнего API.

Толерантность должна быть направленной: потребитель терпим к безопасным расширениям, но строг к нарушениям обязательной части контракта. Например, неизвестное поле можно пропустить, а отсутствие идентификатора или изменение числа на строку — отклонить.

У подхода есть ограничение: он защищает от структурных расширений, но не от изменения семантики существующего поля. Если поставщик начинает трактовать status иначе, потребителю нужны явное изменение контракта, версия или другой механизм согласования.

Ситуация из практики

Поставщик каталога добавил в ответ поле availabilityDetails, описывающее сроки поставки. Старое приложение использовало только id, name и available.

Рассматривались два варианта. Строгий парсер, отклоняющий любые неизвестные поля, проще обнаруживает изменения, но делает безопасное расширение причиной массовых сбоев. Полное игнорирование структуры уменьшает число отказов, однако скрывает повреждённые обязательные данные и ошибки типов.

Выбрали толерантное чтение с проверкой обязательных полей и типов. Новое поле старое приложение игнорировало, а отдельные тесты контракта проверяли, что добавление необязательных полей не нарушает обработку ответа. В результате поставщик выпустил расширение без синхронного обновления клиентов, при этом критические ошибки формата по-прежнему выявлялись на границе интеграции.

Что кандидаты часто упускают

  1. Достаточно ли игнорировать неизвестные поля, если они необязательные?

Нет, сначала нужно проверить, не меняют ли они трактовку известных данных. Новое поле обычно безопасно, когда оно только добавляет независимую информацию. Но поле, влияющее на смысл status, порядок элементов, валюту или единицу измерения, может требовать изменения контракта даже при формальной необязательности.

  1. Как поступить с новым значением уже известного перечисления?

Простое игнорирование неизвестного значения может быть опасно: клиенту нужно выбрать корректное поведение. Для несущественного статуса допустим переход в состояние unknown с безопасным сценарием обработки, а для критического бизнес-решения лучше отклонить ответ или применить явно согласованную стратегию. Политика должна быть определена для каждого перечисления, а не выбираться случайно в коде.

  1. Почему нельзя сделать внутреннюю модель полностью совпадающей с внешним ответом?

Внешний контракт и внутренняя модель меняются по разным причинам и с разной скоростью. Прямое отображение связывает внутреннюю логику со всеми деталями поставщика, поэтому любое расширение или переименование начинает распространяться по системе. Отдельный слой преобразования позволяет игнорировать неподдерживаемые поля, задавать значения по умолчанию и контролировать изменения семантики.