Как описывать API контракт
Что проверяют
Для системного аналитика это вопрос о том, можете ли вы отдать разработчикам обеих сторон документ, по которому они сделают интеграцию без лишних созвонов. Проверяют знание стандарта и умение описать ошибки и граничные случаи, а не только успешный ответ. Следом обычно просят рассказать, как вы меняли контракт, не сломав клиентов.
Как отвечать
Начните с подхода design-first: контракт пишется и согласуется до кода, спецификация становится источником правды. Формат зависит от типа взаимодействия: OpenAPI 3.x в YAML для REST, AsyncAPI для событий в Kafka или RabbitMQ, .proto-файлы для gRPC, SDL-схема для GraphQL.
Что должно быть в контракте:
- ресурсы и методы: пути, HTTP-методы, какие операции идемпотентны. Для
POSTс деньгами оговорите заголовокIdempotency-Key; - схемы данных: типы, обязательность (
required), форматы (date-time,uuid), ограничения длины и диапазона,enum, допустим лиnull. Для каждого поля бизнес-смысл и источник значения; - ошибки: коды статусов с условиями, единый формат тела ошибки, например Problem Details по RFC 9457, список прикладных кодов;
- безопасность: схема аутентификации в
securitySchemesи права на операцию; - поведение: пагинация, сортировка, лимиты запросов, таймауты, ожидаемая нагрузка;
- примеры: запрос и ответ на каждый сценарий, включая ошибочный;
- версионирование: что считается совместимым изменением (новое необязательное поле), что ломающим (переименование, новое обязательное поле), как объявляется новая версия.
Проверку автоматизируют: линтер Spectral, мок-сервер по спецификации для раннего старта фронтенда, Pact для контрактов со стороны потребителя.
Где спотыкаются
Описывают только «счастливый путь». Разработчик сам придумывает ответ на пустой список или неверный параметр, и у двух команд получаются разные ожидания.
Путают контракт с документацией после факта. Спецификация, сгенерированная из готового кода, фиксирует то, что написали, а не то, о чём договорились.
Не оговаривают обязательность и null. Для клиента отсутствующее поле, поле со значением null и пустая строка ведут себя по-разному.