сеньорчикОткрыть в Telegram
← вся теориятеория к собесу · ТЗ и документация

Спецификация API

Спецификация API

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

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

// Формулировки: «что опишешь для метода?», «какое изменение сломает клиентов?», «как выкатить несовместимую правку?»

Ошибки - половина контракта

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

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

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

Совместимость: расширять можно, сужать нельзя

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

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

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

// Полезно закладывать это в спецификацию явно, отдельным предложением: «потребители обязаны игнорировать неизвестные поля». Тогда добавление поля перестаёт быть событием, требующим согласования со всеми.

обратная совместимость
свойство изменения, при котором уже работающие клиенты продолжают работать без правок у себя

Как выкатывать несовместимое

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

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

// Отдельная беда - спецификация, написанная после реализации. Потребители кодируют по описанию, а поведение отличается, и падают они уже в бою. Лечится генерацией описания прямо из кода или контрактными тестами, которые роняют сборку при расхождении реального ответа со схемой.

Как отвечать: «Поле сумма приходит строкой, хотим сделать числом. Как?»

Это несовместимое изменение: клиент, который ожидает строку, упадёт прямо на разборе ответа. Поэтому тип на месте не меняю. Добавляю новое поле рядом, даю потребителям объявленное окно на переход, по метрикам смотрю, кто ещё читает старое, дожимаю отстающих адресно и только потом удаляю прежнее поле в следующей мажорной версии. И отдельно я бы переспросил, зачем вообще менять: для денежных значений строка часто оказывается осознанным выбором против потери точности при разборе числа с плавающей точкой. Вполне возможно, что менять не нужно вовсе, а нужно просто описать в спецификации, почему там строка.

Кандидат даёт безопасную процедуру и заодно ставит под сомнение саму задачу, причём с обоснованием по существу предметной области, а не из желания поспорить.

На чём валятся

  • − Описывают только успешный ответ, оставляя ошибки на усмотрение реализации.
  • − Возвращают ошибку с кодом успеха и ослепляют мониторинг.
  • − Меняют тип поля внутри версии, считая правку косметической.
  • − Пишут спецификацию после реализации, и она расходится с реальным поведением.
  • − Ограничиваются примерами без схемы: не заданы обязательность полей и границы значений.

Проверьте себя

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

  1. #ana_doc_api_spec1 / 5
    Зачем в спецификации примеры запросов и ответов, если схемы уже описаны?
    A)Примеры снимают разночтения быстрее схемы
    B)Примеры заменяют собой описание полей
    C)Без примеров спецификация считается недействительной
    D)Примеры нужны только для внешних потребителей
    показать ответ и разбор
    +A)Примеры снимают разночтения быстрее схемы

    // разбор: Схема задаёт форму, но не смысл: по ней не видно, как выглядит реальный идентификатор, в каком формате приходит дата и что лежит в поле при отсутствии значения. Живой пример снимает эти вопросы за секунды и служит основой для тестов и заглушек, поэтому его держат рядом со схемой.

  2. #ana_doc_api_spec2 / 5
    Спецификация написана после реализации и расходится с ней. Чем это опасно сильнее всего?
    A)Документ выглядит неаккуратно при аудите
    B)Растёт объём работы технического писателя
    C)Спецификация занимает лишнее место в репозитории
    D)Потребители пишут код по описанию и ломаются на проде
    показать ответ и разбор
    +D)Потребители пишут код по описанию и ломаются на проде

    // разбор: Контракт ценен ровно настолько, насколько ему можно доверять. Если поле в описании обязательное, а на деле приходит пустым, соседняя команда обнаружит это уже в бою. Лечится генерацией спецификации из кода либо контрактными тестами, которые роняют сборку при расхождении.

  3. #ana_doc_api_spec3 / 5
    Что означает обратно совместимое изменение API?
    A)Изменение согласовано со всеми потребителями
    B)Изменение внесено в новую мажорную версию
    C)Старые клиенты продолжают работать без правок
    D)Изменение затрагивает только внутренние сервисы
    показать ответ и разбор
    +C)Старые клиенты продолжают работать без правок

    // разбор: Совместимость определяется по клиенту, а не по договорённостям: добавление необязательного поля или нового метода безопасно, а удаление поля, ужесточение валидации и смена типа — нет. Практическое правило: расширять можно, сужать нельзя. Сужение требует новой версии и срока миграции.

  4. #ana_doc_api_spec4 / 5
    В ответе метода поле «сумма» приходит строкой. Аналитик хочет заменить на число. Что учесть?
    A)Смена типа ломает клиентов — нужна версия и срок перехода
    B)Замена безопасна, если предупредить в чате
    C)Достаточно обновить примеры в документации
    D)Смена типа допустима внутри одной версии
    показать ответ и разбор
    +A)Смена типа ломает клиентов — нужна версия и срок перехода

    // разбор: Изменение типа — несовместимая правка: клиент, ожидающий строку, упадёт на разборе ответа. Аккуратный путь — добавить новое поле рядом, дать потребителям срок на переход, затем удалить старое в следующей мажорной версии. Для денег, кстати, строка часто оказывается осознанным выбором против потери точности.

  5. #ana_doc_api_spec5 / 5
    Потребителей API много, и все обновляются по-разному. Как выкатить несовместимое изменение?
    A)Выкатить сразу — потребители подстроятся
    B)Новая версия рядом со старой и окно миграции
    C)Согласовать общий день переключения для всех
    D)Отложить изменение до полного переписывания системы
    показать ответ и разбор
    +B)Новая версия рядом со старой и окно миграции

    // разбор: Одномоментное переключение требует синхронного релиза у всех потребителей и почти никогда не выполнимо. Рабочая схема: поднять новую версию параллельно старой, объявить дату вывода старой из эксплуатации, отслеживать по метрикам, кто ещё на ней сидит, и адресно дожимать отстающих.

дальше

Теорию прочитали. Навык ставится повторением

В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.