Как договариваться с бекенд-разработчиками и есть ли описанные контракты
Что проверяют
Как вы работаете, когда API ещё нет или оно меняется, и есть ли у вас привычка договариваться о контракте до кода. Этот же вопрос часто задаёт сам кандидат работодателю, и по ответу видно, насколько в команде налажен процесс.
Как отвечать
Опишите свой процесс на примере из опыта: что за фича, в каком виде был контракт, что пошло не так и как вы это исправили. Каркас:
- контракт до реализации: схема OpenAPI для REST, SDL для GraphQL или
.protoдля gRPC. Её обсуждают в PR так же, как код, и фронтенд участвует в ревью, а не получает готовое; - типы из схемы: генерация TypeScript-типов и клиента, например
openapi-typescriptилиorvalдля REST и GraphQL Code Generator. Расхождение со схемой становится ошибкой компиляции, а не багом на проде; - работа без готового бекенда: моки по той же схеме, через MSW в браузере и тестах или Prism, который поднимает мок-сервер из OpenAPI;
- что проговаривать отдельно: формат ошибок (удобно взять RFC 9457, Problem Details), пагинацию,
nullпротив отсутствующего поля, форматы дат и денег; - изменения: ломающие правки только через новую версию или через период, когда старое поле помечено
deprecated. Для контроля есть контрактные тесты, например Pact, где потребитель фиксирует, что он реально использует.
Если контракты в прошлой команде не описывались, так и скажите и объясните, как вы с этим жили и что предлагали изменить. Это честнее и полезнее рассказа об идеальном процессе.
Если вопрос задаёте вы, уточните: есть ли OpenAPI, генерируется ли он из кода или пишется руками, кто его владелец и как команда узнаёт о ломающих изменениях.
Где спотыкаются
Отвечают «договариваемся в чате». Устная договорённость живёт до первого отпуска, и через месяц никто не помнит, почему поле называется именно так.
Молча подстраиваются под странности API на фронтенде: переименовывают поля, склеивают запросы, чинят форматы. Логика расползается по компонентам, и её никто не видит.
Не отличают опциональное поле от поля со значением null. Для TypeScript это разные типы, и именно здесь чаще всего ломается сгенерированный клиент.