Перестал чинить фронт руками. Сэкономил 15 часов в неделю

Знаете то чувство, когда ты уверен, что всё работает, а прод снова падает?

На прошлой неделе я заново открыл для себя это чувство.

Локально всё летало. На стейдже ошибка. Бэкендер переименовал поле в ответе. Не сказал. Не обновил документацию.

Я узнал об этом, когда код упал. И пошёл разбираться с ошибкой вместо того, чтобы продумывать архитектуру следующего модуля.

В этот момент я понял: так больше нельзя.

После этого случая я поднял вопрос на ретро. Мы договорились: теперь изменения в контракте сначала попадают в сваггер, потом в код.

Я перебрал несколько генераторов: openapi-generator, orval, swagger-typescript-api. Остановился на @hey-api/openapi-ts. Он даёт чистый код и легко настраивается под наш стек.

Я перешёл на генерируемый API-клиент.

Это набор ручек и типов, которые генерируются на основе открытого API - yaml-файла сваггера.

Теперь я просто ввожу в терминал: npm run openapi:pull

И получаю папку api/generated/ с двумя главными файлами:

- все ручки (функции для запросов) - все типы (описания структуры данных)

Ручные правки ушли в прошлое. Вместе с ними ушли «ой, забыл поправить» и часы на синхронизацию.

Как это выглядит под капотом?

1. Скачиваю свежий openapi.yaml с бэкенда через curl 2. Генерирую клиент через @hey-api/openapi-ts 3. Коммичу и spec, и сгенерированный код

generated/ руками не трогаю. Только через генерацию.

Я описал этот подход в ридми для команды. Теперь любой новичок понимает API-слой с первого дня.

Что изменилось?

В коде всегда актуальные поля. TypeScript сам подскажет, если я ошибся в имени или типе. IDE подсвечивает ошибки на этапе написания.

Исчезла головная боль с расхождениями в контракте. Раньше я тратил часы, чтобы понять: фронт неправильно стучится или бэк неправильно отвечает?

Теперь все ручки, их назначение и типы данных лежат прямо в коде проекта. Даже сваггер открывать не нужно.

Новый разработчик на проекте? Прочитал ридми и уже знает, куда смотреть. Время на онбординг сократилось.

15 часов в неделю - это не просто цифра, а две дополнительные фичи за спринт. Или время на рефакторинг, который мы вечно откладывали.

Но куда же без подводных камней?

oneOf / anyOf. Генератор не всегда красиво обрабатывает сложные схемы. Приходится дописывать гарды.

Сваггер не совпадает с реальностью. Типы говорят одно, приходит другое. TypeScript в этом случае не просто бесполезен, он активно мешает. Единственный способ успокоить компилятор - писать проверки и as-касты.

Трансформация данных. Сгенерированные DTO - это не доменные модели. Иногда оборачиваю их в адаптеры.

Храню openapi.yaml в репозитории, чтобы сборка не падала, если бэк недоступен.

Это работает. Я возвращаться к ручному написанию ручек не планирую.

А как у вас?

Генерируете API-клиенты или всё ещё пишете руками? Если генерируете, каким инструментом пользуетесь?

Бывало, что бэк менял поле, а вы узнавали об этом на проде? Делитесь в комментариях.

Перестал чинить фронт руками. Сэкономил 15 часов в неделю | Сетка — социальная сеть от hh.ru