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

Поле переименовали, старый клиент об этом не узнал
Учебная история: у компании есть приложение и интеграция с партнёром. Разработчики заменили поле contact_phone на более красивое phone. Новый интерфейс работает, тестовый запрос проходит. Партнёрский клиент продолжает отправлять прежнее имя. Сервер принимает сообщение, но телефон до сотрудника не доходит. В журнале всё ещё успешный ответ. В работе — неполная заявка.
Так выглядит изменение API, которое проверили только новой версией клиента. Обратная совместимость требует другого вопроса: сможет ли прежний потребитель продолжить согласованную работу без одновременного обновления? Синтаксически корректный JSON и ответ сервера не доказывают сохранение смысла. Иногда самая неприятная поломка не вызывает технической ошибки вообще.
Разберём одно развивающееся API глазами владельца бизнес-интеграции. Что считать изменением договора, как проверить старого клиента, где нужен переходный период и когда можно прекратить прежнюю версию? Это не полный курс проектирования интерфейсов. Главный результат — таблица изменений и набор сохранённых примеров, по которым команда принимает релиз.
Контракт — больше, чем список полей
В контракт входят названия, типы, обязательность, допустимые значения и смысл. Поле может остаться числом, но перейти из одной единицы в другую. Статус может остаться строкой, но получить новое значение. Формат будет валиден, а старое приложение примет неверное решение. Поэтому договорённость должна описывать не только возможность разобрать сообщение.
Для каждого важного поля полезно знать, что делает потребитель. Показывает человеку, использует в расчёте, выбирает дальнейшее действие или хранит для проверки? Чем существеннее последствие, тем важнее сохранённый пример ожидаемого поведения. Один и тот же новый статус безвреден для журнала и опасен для автоматического решения закрыть задачу.
Google в AIP-180 об обратной совместимости рассматривает изменение опубликованного контракта с учётом существующих клиентов. Это рекомендации конкретной API-системы, а не автоматическое доказательство совместимости вашего обмена.
Зафиксируйте также трактовку отсутствия, пустого значения и нуля. Если раньше отсутствие поля означало «неизвестно», новый сервер не должен незаметно превращать его в отрицательное решение. Такой сдвиг часто не виден схеме. Его обнаруживает предметный пример: старый клиент не передал параметр, а бизнес-процесс продолжился так, будто параметр проверили.
Проверить изменение в обе стороны
Есть два основных сочетания: старый клиент с новым сервером и новый клиент с прежним сервером переходного периода. Проект может требовать оба или только определённое направление. Важно назвать это явно. Фраза «совместимо» без указания версий скрывает половину вопроса и создаёт разные ожидания у команд.
Условная компания выпускает сервер раньше мобильного приложения. Значит, старые установки должны некоторое время работать с новым API. Если партнёр обновляет свой клиент по отдельному графику, период может отличаться. Нельзя автоматически назначать одинаковую дату всем потребителям. Сначала нужен реестр действующих клиентов и их владельцев.
Новый клиент со старым сервером тоже встречается, если релиз распространяется поэтапно или серверные узлы обновляются не одновременно. Тогда дополнительные поля и методы должны иметь предсказуемый выход. Иногда новый сценарий временно недоступен. Это лучше, чем молчаливое частичное выполнение, после которого человек считает задачу завершённой.
Необязательно поддерживать все сочетания бесконечно. Можно определить ограниченную матрицу и управляемый отказ для остальных. Но неподдерживаемый клиент должен получить понятное состояние, а компания — способ увидеть его использование. Отказ не должен маскироваться под успех с потерянными данными. Иначе прекращение поддержки обнаружат покупатели, а не мониторинг.
Добавить поле, убрать поле, сделать поле обязательным
Добавление необязательного поля часто выглядит безопасно, но зависит от поведения потребителя. Один игнорирует неизвестные свойства, другой требует точного набора. Поэтому даже такое изменение проверяют на действующих клиентах. Нельзя объявить его совместимым только по общему правилу из документации. Решает фактический контракт и реализация разбора.
Удаление или переименование затрагивает тех, кто использует прежнее имя. Для перехода можно поддерживать старое и новое представление с определённым правилом при одновременной передаче. Например, если оба значения отличаются, сервер возвращает явное противоречие или применяет заранее согласованное поведение. Молчаливый выбор удобного поля создаёт новую двусмысленность.
Новое обязательное поле в запросе ставит старого клиента в невозможное положение: он не знает, что его нужно отправить. Возможны отдельная версия или переходный способ заполнения, если он действительно корректен для бизнеса. Но придумывать значение по умолчанию только ради успешного ответа опасно. Условный регион поставки нельзя назначить случайно, если от него зависит доступность услуги.
Новое обязательное поле в ответе — другой случай. Сервер может гарантировать его наличие новой версии клиента, но старые данные ещё не содержат нужного значения. Понадобится миграция, явная неизвестность или исключение. Нельзя обещать строгое поле, которое система заполняет фиктивной строкой для прохождения проверки. Формальная полнота и пригодность данных различаются.
Самый тихий дефект: новый статус
Предположим, старый клиент знает ready и failed. Команда добавляет needs_review, потому что теперь часть случаев требует сотрудника. JSON корректен, поле осталось строкой. Но старый интерфейс показывает все незнакомые статусы как готовность. В результате задача, ожидающая проверки, оказывается завершённой в глазах человека. Это учебный пример поведенческой несовместимости.
Нужен тест реакции на неизвестное значение. Потребитель может безопасно остановить действие, показать ограниченное состояние или сохранить незнакомый статус для разбора. Конкретный вариант выбирается по риску. Главное — не приравнивать неизвестность к наиболее удобному исходу. В договоре следует отдельно описать расширяемость перечислений и допустимое поведение клиента.
Проверять полезно не только новый статус, но и сочетание полей. Например, ready вместе с отсутствующим документом может быть допустимым в одном сценарии и ошибочным в другом. Схема покажет типы, но предметная проверка устанавливает согласованность. Владелец интеграции должен знать, какие условия необходимы для дальнейшего действия.
Есть ещё изменение смысла прежнего статуса. Название осталось, но теперь оно возникает раньше. Старый клиент начинает следующий шаг, хотя работа ещё продолжается. Такой релиз особенно легко пропустить при сравнении схем. Поэтому для ключевых состояний нужны временная последовательность и проверяемый смысл завершения, а не только словарь значений.
Номер версии не чинит договорённость
Можно обозначать версию в адресе, параметре или заголовке. В рекомендациях Microsoft по API описаны разные способы версионирования. Выбор механизма не отменяет обязанность определить совместимость и период поддержки.
Если переименованное поле просто перенесли в /v2/, старый клиент всё ещё нуждается в работающем /v1/ до согласованной границы. Иначе новая цифра только объясняет название поломки. Версия помогает выбрать договор, но не создаёт его автоматически. Необходимо поддерживать соответствующий обмен и понимать, кто им пользуется.
Иногда достаточно совместимого расширения текущей версии. Иногда изменение настолько существенно, что переходный адаптер станет сложнее отдельного интерфейса. Решение зависит от числа клиентов, длительности поддержки и цены ошибки. Не стоит плодить версии на каждую косметическую правку, но и скрывать изменение поведения под прежним номером неудобно для потребителей.
В документации Stripe о версиях описана привязка версии запросов к настройкам и явному переопределению. Это пример наблюдаемого выбора контракта, а не рекомендация использовать платёжный сервис для любой интеграции.
Полезно видеть применённую версию в диагностике конкретного запроса. Тогда поддержка может восстановить поведение, которое ожидал клиент. Если версия существует только в названии релизной задачи, проблему приходится угадывать по дате установки и памяти команды. Контракт должен быть наблюдаемым в работе, а не только в документе.
Таблица изменений, которую понимают обе стороны
Для небольшого API достаточно короткого реестра существенных правок. В каждой строке есть изменение, влияние на старого и нового потребителя, переходное решение, тест и срок прекращения. Это рабочий документ, а не попытка переписать всю спецификацию. Ниже — заготовка для обсуждения конкретного релиза.
| Изменение | Проверка и переход |
|---|---|
| Переименование свойства | Старое имя принимается по правилу или используется отдельная версия |
| Новое обязательное поле | Старый запрос имеет явный допустимый исход |
| Новый статус | Старый клиент не принимает неизвестность за успех |
| Новая единица значения | Смысл и контрольный расчёт сохранены |
| Удаление метода | Известны потребители и дата прекращения |
| Изменение пустого значения | Проверены отсутствие, null и содержательное значение |
Рядом с таблицей нужны владельцы клиентов. Для внутреннего интерфейса это может быть одна команда. Для партнёрского — несколько разных организаций. Если потребитель неизвестен, в плане миграции остаётся риск. Нельзя закрыть его фразой «всем отправили уведомление», не понимая, кто должен принять изменение и подтвердить проверку.
Дата прекращения должна быть предметной договорённостью проекта, а не выдуманным универсальным стандартом. Нужно время на получение сообщения, разработку, испытание и выпуск потребителя. Если клиент не обновился, заранее определяют действия. Бессрочно хранить старую реализацию и внезапно выключить её одинаково неудобно; управляемый переход находится между этими крайностями.
Сохранённые примеры сильнее красивой новой схемы
Перед изменением возьмите допустимые обезличенные запросы и ожидаемые ответы для основных сценариев. Сохраните не только JSON, но и смысл результата: какие поля человек должен увидеть, какое действие разрешено, что остаётся неизвестным. Затем прогоните эти контракты через новую реализацию. Такой набор проверяет обещанную работу, а не только синтаксис.
Нужны обычные и неудобные случаи: отсутствующее необязательное поле, пустой список, старый статус, неизвестное значение, противоречивые имена, граничное число. Не обязательно делать огромный набор до первого изменения. Важнее выбрать примеры, на которых реально принимаются бизнес-решения. Один позитивный запрос редко обнаруживает тихую потерю контакта или неверное завершение задачи.
Отдельно запускается прежний потребитель. Серверный тест может подтвердить формат, но не увидеть особенности старого клиента. Если тот падает на неизвестном поле или неверно отображает статус, совместимость ещё не достигнута. Поэтому проверка должна доходить до поведения принимающей стороны, а не завершаться зелёным ответом HTTP.
Для обмена через тестовый стенд интеграции важно отделить готовую среду от пройденного контракта. Наличие стенда даёт место испытанию, но не подтверждает, что нужные сочетания версий действительно проверены. В отчёте остаются конкретные входы, выходы, версии и непройденные случаи.
Наблюдать переход, а не ждать первого обращения поддержки
После выпуска полезно видеть использование версий и типы ошибок. Кто ещё обращается по прежнему договору? Какие поля не проходят? Где появились неизвестные состояния? Эти сведения помогают завершать миграцию. Без них старый интерфейс либо поддерживают вечно на всякий случай, либо выключают вслепую.
Не вся диагностика требует хранить полный запрос. Часто достаточно версии, типа операции, кода результата и допустимого идентификатора трассировки. Состав данных определяется проектом. Нельзя превращать наблюдение за совместимостью в бесконтрольное накопление содержимого всех заявок. Воспроизводимость должна быть соразмерна задаче и доступным полномочиям.
Для ошибок полезно различать неподдерживаемую версию и неверные данные внутри поддерживаемой. У них разные действия. В первом случае нужен переход потребителя, во втором — исправление конкретного сообщения. Если оба варианта попадают в общий «сбой API», команда может обновлять клиент, который на самом деле передаёт неправильный артикул.
При поэтапном выпуске сохраняйте дату и состав изменений. Иначе невозможно объяснить, почему одинаковый запрос дал разные результаты в разные моменты. Версия логики и версия данных могут меняться независимо. В рабочем разборе это не академическая тонкость: один и тот же формат способен участвовать в нескольких разных реализациях поведения.
Откат не всегда возвращает совместимость
Возврат серверного кода может остановить новый дефект, но не обязательно восстановит прежнее состояние. За время релиза могли появиться данные нового формата или потребители, уже использующие новые поля. Поэтому план отката должен учитывать направления перехода. Иначе исправление одного клиента сломает другого, который успел обновиться по вашему же плану.
Для важных изменений заранее проверяют, может ли старая реализация читать новые записи. Если нет, выбирают иной способ восстановления: совместимую исправленную версию, ограничение новых операций или предусмотренную миграцию. Конкретное решение зависит от архитектуры. Универсальная кнопка «вернуть вчерашнее» не является доказательством возможности безопасного возврата.
Тот же вопрос относится к новым статусам. Если часть задач уже находится в needs_review, прежний сервер должен либо понимать их, либо получать предусмотренное представление. Удаление незнакомого значения из схемы не устраняет сами задачи. Это одна из причин сохранять контрольные примеры и миграционные решения рядом с релизом.
Сколько стоит не ломать старого клиента
Совместимость требует времени: инвентаризации потребителей, переходных правил, тестов и сопровождения нескольких состояний. Эти расходы стоит обсуждать до оценки разработки. Если сравнивать только скорость написания нового обработчика, поддержка старой стороны будет выглядеть лишней. Но бизнес покупает продолжающийся обмен, а не один удачный запрос из новой документации.
С другой стороны, не всякая старая версия заслуживает бессрочной поддержки. Нужны наблюдаемое использование, владелец и план завершения. Удалённый или неиспользуемый потребитель — другая ситуация, чем действующий партнёр с согласованным графиком. Решение должно опираться на факты использования и обязательства проекта, а не на раздражение от старого кода.
В разработке для бизнеса полезно включать матрицу совместимости в состав приёмки. Тогда понятно, какие сочетания поддерживаются, на каких примерах это проверено и что остаётся ограничением. Примерный состав проверки можно подготовить раньше полной оценки. Это уменьшает вероятность, что важнейший потребитель обнаружится только в день выпуска.
Структурированный ответ нейросети — смежный, но другой предмет. В статье о JSON-ответах обсуждается получение и проверка формы вывода. Здесь договор уже существует между программами и меняется со временем. Корректная структура одного ответа не доказывает, что прежний клиент продолжит выполнять прежнюю задачу.
Что должно остаться после согласования релиза
Список действующих потребителей, таблица изменений, сохранённые контрактные примеры, матрица версий и способ наблюдения. Для прекращаемой версии — дата, владелец перехода и предусмотренный исход после неё. Для отката — проверенное объяснение судьбы новых данных. Это небольшой, но законченный набор, по которому можно обсуждать готовность.
Попросите команду пройти исходную учебную историю: старый клиент отправляет contact_phone, новый сервер ожидает phone. Где именно будет принято решение? Что увидит сотрудник? Как система обнаружит потерю? Если ответ содержит только «нужно обновить клиента», переход пока не спроектирован. Старый потребитель не исчезает от того, что новая документация стала аккуратнее.
Хорошее изменение API заметно прежде всего сохранённой работой. Клиенты обновляются по понятному плану, данные не пропадают молча, неизвестные состояния не становятся успехом. Номер версии помогает управлять этим договором. Сам договор подтверждается поведением на известных примерах и реальным продолжением обмена.
Источники и границы разбора
Проверено 3 ноября 2026. Документы платформ подтверждают отдельные механизмы и определения. Предлагаемые маршруты и условные примеры — авторская методика, а не отчёт о внедрении или обещание клиентов.
- Google AIP-180 — Backwards compatibility
Открыты рекомендации изменения опубликованного контракта. Не доказывают совместимость конкретного клиента без его проверки.
- Microsoft Azure — Web API design best practices
Открыто описание способов версионирования. Механизм номера или заголовка не заменяет переходный план и приёмку.
- Stripe — Versioning
Открыт пример явного выбора версии запроса. Не является рекомендацией платёжного сервиса или универсальным регламентом чужого API.