В мае 2020-го Facebook изменил формат данных, которые отдаёт его SDK. Одно серверное изменение — и TikTok, Spotify, Tinder, Pinterest перестали открываться. Миллионы пользователей. Разработчики этих приложений не меняли ни строчки кода — приложения просто упали на парсинге при запуске. Через два месяца Facebook сделал это снова: тот же баг, те же приложения.

В мобилке одновременно живут 5–10 версий приложения. Ты не можешь нажать кнопку «обновить всех» — и бэкенд обязан работать со всеми сразу.

Главное правило: контракт только расширять

API-контракт можно только расширять — и никогда не ломать.

Добавить новое поле в ответ обычно безопасно: старый клиент его проигнорирует — но только если он реализует толерантный парсинг, то есть молча пропускает неизвестные поля. Это не магия, а осознанное решение мобильного разработчика. А вот убрать поле, переименовать или поменять тип — сломает всех, кто на старой версии.

Как это выглядит на практике

Версионируй на уровне сообщений, а не URL. Клиент в каждом запросе шлёт свой capabilities-bag (список того, что он умеет), сервер отвечает поддерживаемым подмножеством. Это дешевле, чем плодить v1/v2/v3 в путях, и закрывает 80% случаев.

request.capabilities = [
  "reactions.v2",
  "transcript.live",
  "ai.summary"
]
capabilities-bag: клиент шлёт список возможностей, сервер отвечает поддерживаемым подмножеством, старый клиент молча игнорирует новое поле

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

Когда отрезать старые версии — Сбер против Telegram

Сбер просит обновиться каждый месяц, Telegram почти никогда — и оба правы. Банку проще отрезать старые версии: регуляторика, безопасность, и ты всё равно никуда не уйдёшь. У Telegram половина аудитории на дешёвых Android в Иране и Индии — force update для них означает потерять рынок. Это не «правильно/неправильно», а разный профиль рисков.

Что закладывать в ТЗ аналитику

Если пишешь требования на мобильную фичу — фиксируй в ТЗ три вещи: минимальную поддерживаемую версию, что видит пользователь на старой версии (фича скрыта? деградирует? показывает заглушку?) и когда можно отключить поддержку. Я считаю, что grace period в 3 месяца — разумный максимум: если пользователь не обновился за это время, он практически не твой пользователь.

Когда контракт умеет отвечать «как раньше», если клиент об этом просит, — выкатывать изменения перестаёт быть страшно. Контракт становится переговорами, а не ультиматумом.