OpenAPI из диалога: простой процесс из 3 шагов (спека, мок-ответы, обвязка) и способы находить несовпадения еще до разработки.

Когда API обсуждают на словах, почти всегда остаются дыры: как называется поле, какие статусы возможны, что делать при ошибке, где пагинация, какой формат дат. Каждый понимает по-своему, и это всплывает поздно. Фронтенд ждет items, бэкенд отдает data; клиент отправляет строку, сервер ждет число; один считает, что должен быть 404, другой возвращает 200 с пустым массивом.
Контрактное проектирование API решает это простой фиксацией правил до кода. Спецификация становится общей точкой правды: ее читают люди, по ней строят проверки, по ней можно генерировать заготовки. Главное преимущество в том, что правки в контракте дешевы: вы меняете текст, схемы и примеры. Правки в коде обычно дороже: приходится трогать обработчики, миграции, документацию, автотесты и, хуже всего, передоговариваться, когда уже кажется, что «все сделали».
Выигрывают сразу несколько ролей. Продукт получает понятные сценарии и ожидаемые ответы без «магии реализации». Фронтенд может начать верстку и интеграцию по мок-ответам, не дожидаясь готового сервера. Бэкенду проще стартовать реализацию, потому что границы заранее определены. Тестирование получает список проверок: статусы, ошибки, обязательные поля, примеры.
На старте достаточно договориться о базовом наборе артефактов: список эндпоинтов (метод, путь, параметры), модели данных (поля, типы, обязательность), правила ошибок (коды и формат тела), а также примеры запросов и ответов для ключевых сценариев.
Если вы работаете в TakProsto, удобно сначала проговорить API в чате и получить черновик спецификации. Но смысл не в инструменте, а в привычке: сначала контракт, потом реализация. Так вы снижаете число несовпадений еще до разработки.
OpenAPI из диалога лучше всего получается, когда вы сначала даете понятные вводные, а уже потом просите собрать YAML или JSON. Если начать с запроса «сгенерируй спецификацию», часто получается аккуратный, но слабый документ: без единых правил, с размытыми статусами и без примеров.
Сначала коротко опишите сервис и границы: что он делает и чего точно не делает. Затем перечислите основные сущности и сценарии. Например: «заявка», «пользователь», «статус заявки», «создать заявку», «посмотреть список», «отменить».
Чтобы черновик сразу был практичным, в диалоге заранее задайте рамки: кто вызывает сервис (веб, мобайл, интеграция), какие сущности и поля обязательны (id, статусы, даты), какие 5-7 сценариев важнее всего (успешные и ошибочные), а также ограничения вроде авторизации, ролей, лимитов и идемпотентности для критичных операций.
Дальше формулируйте требования к эндпоинтам через поведение: какой метод, какой ресурс, какие статусы и почему. Сразу просите примеры запросов и ответов для каждого сценария, включая ошибки (400, 401, 403, 404, 409, 422, 500) и структуру error-ответа.
Отдельно зафиксируйте правила, из-за которых чаще всего возникают споры: пагинация (limit/offset или cursor), фильтры и сортировка, формат дат, нейминг полей (snake_case или camelCase), версионирование (например, /v1), единый подход к пустым значениям.
Собери черновик OpenAPI 3.0.
Контекст: сервис заявок.
Сущности: Application {id, title, status, createdAt}, User {id, name}.
Сценарии: создать, получить по id, список с фильтром по status, отмена.
Требования:
- Версия API: /v1
- Пагинация: limit/offset
- Ошибки: единый формат {code, message, details}
- Для каждого эндпоинта дай: описание, параметры, статусы, примеры request/response.
Если вы делаете это в TakProsto, полезная добавка к запросу: «после черновика перечисли спорные места и вопросы к заказчику». Это помогает поймать расхождения ожиданий до разработки и не переделывать контракт после первых тестов клиента.
Цель первого шага простая: получить OpenAPI, по которому можно спорить предметно, проверять сценарии и генерировать заготовки, а не просто читать «описание API». Если спецификация рождается из диалога, решения лучше сразу фиксировать в документе, иначе они потеряются в переписке.
Сначала выберите версию (OpenAPI 3.0 или 3.1) и формат (JSON или YAML). Чаще всего 3.0 в YAML хватает: его легче читать и править руками. 3.1 полезен, если вам важны более новые возможности JSON Schema. Важнее всего, чтобы версия была одна для всех сервисов, иначе инструменты начнут вести себя по-разному.
Дальше описывайте API через операции: путь, метод, назначение и коды ответов. POST /orders - это не просто «создает заявку», а операция, которая возвращает 201 с телом, 400 при ошибке валидации, 401/403 при проблемах доступа, 409 при конфликте (например, дубль).
Минимум, без которого спецификация обычно «не работает»:
401 и 403;code, message, details, плюс requestId или traceId в каждом ответе.Ошибки и идентификаторы запроса стоит договорить сразу. Когда клиент видит requestId/traceId в любом ответе, ему проще обращаться в поддержку и искать проблему в логах. Если вы используете TakProsto для генерации черновика, попросите сразу добавить стандартную схему ошибки и поле traceId, чтобы потом не править десятки операций.
Быстрая проверка «на пригодность»: по одному эндпоинту должно быть понятно, какие поля обязательны, что вернется при типичных ошибках и как клиент отличит «нет прав» от «не найдено». Если ответ неочевиден, это пробел в контракте, а не «деталь реализации».
Даже если вы собираете OpenAPI из диалога, без заранее согласованных правил спецификация быстро расползается. Один клиент ждет ISO-дату, другой - таймстамп, а сервер возвращает «как получилось». Эти мелочи потом стоят дороже, чем само написание эндпоинта.
Обычно хватает нескольких решений, но они должны быть едиными для всего API: стиль пагинации, форматы дат и денег, правила enum и пустых значений, идемпотентность для создания, единый формат ошибок и единый нейминг полей.
Пагинацию выбирают по характеру данных. Limit/offset проще и удобен для админок и небольших списков. Cursor полезнее, когда список часто меняется и важна стабильная прокрутка без сюрпризов из-за вставок и удалений.
С форматами важен не вкус, а проверяемость. Для дат чаще всего берут ISO 8601 строкой. Для денег надежнее целое число в минимальных единицах (копейки), а не float. Для enum заранее решите, будут ли значения строковыми или числовыми, и что вы делаете, если появится новое значение.
Идемпотентность особенно важна для операций создания: клиент может повторить запрос из-за таймаута. Простое правило - принимать Idempotency-Key и возвращать один результат на ключ в разумное время.
Ошибки лучше нормализовать: code для машин, message для человека, details для полей. Тогда у вас в разных сервисах не появятся «invalid_input» здесь и «bad_request» там.
Если вы собираете это в TakProsto, удобно фиксировать соглашения в Planning mode, а потом использовать их при генерации обвязки и тестовых ответов.
Мок-ответы нужны сразу. Они позволяют фронтенду собрать экраны и состояния, тестировщикам прогнать сценарии, а команде увидеть, где контракт неудобный или неполный. Черновик OpenAPI из диалога превращается в проверяемую договоренность.
Достаточно покрыть не только «идеальный день», а несколько типовых вариантов: успешный ответ с обычными данными, успех с пустым результатом (например, список без элементов), случай с отсутствующими необязательными полями, ошибка валидации (400), ошибки доступа (401/403) и «не найдено» (404).
Важно, чтобы примеры были реалистичными: даты в одном формате, строки разумной длины, суммы без «магических» значений. Добавьте пару граничных случаев (0 и 1, максимальные длины, пустые строки, редкие статусы) - часто именно здесь всплывают вопросы «поле обязательное?» и «что возвращаем, если нет прав?».
Храните примеры рядом со схемами, иначе они быстро разъедутся. Практично держать по 1-2 примера на ключевую schema/response и обновлять их вместе с изменениями полей.
Прогонять сценарии можно без реального бэкенда: поднять мок-сервер по OpenAPI и переключить на него фронтенд. В TakProsto это удобно делать отдельным шагом в проекте: сначала фиксируете контракт и примеры, потом переходите к каркасу и бизнес-логике.
Проверка на этом этапе простая: если интерфейс легко собирается на моках, а ошибки понятны и одинаковы по формату, контракт готов к реализации.
Когда спецификация готова и проверена мок-ответами, выгодно превратить ее в рабочий каркас сервера. Так вы начинаете с согласованного контракта, а не с догадок.
Генерация обычно закрывает рутину: маршруты и заглушки обработчиков, модели запросов и ответов, валидацию входных данных по схеме, базовую сериализацию и каркас ошибок, а также документацию из той же спецификации.
Дальше выбирайте язык и стек так, чтобы команда реально поддерживала это годами. Если бэкенд на Go и база PostgreSQL, логично генерировать каркас под Go, а типы ошибок и модели держать рядом с транспортным слоем. В TakProsto это хорошо ложится на типичный стек React для веба и Go + PostgreSQL для бэкенда.
Важно провести границу: генерация отвечает за «края» (HTTP, типы, валидацию), а ручной код - за смысл. Бизнес-правила, сервисы, репозитории и интеграции не стоит пытаться генерировать: они меняются чаще и требуют осознанных решений.
Чтобы контракт не «уплыл», договоритесь об одном источнике правды: правим OpenAPI, затем пересобираем обвязку. Ручные правки в сгенерированных файлах лучше запретить, иначе через неделю будет непонятно, что именно считается правильным.
Удобная структура проекта помогает не смешивать автокод и логику. Например, отдельно хранить спецификацию и артефакты генерации, отдельно транспортный слой, отдельно бизнес-логику и доступ к данным.
Пример: вы добавили поле priority в запрос создания заявки. Меняете схему, генератор обновляет модель и валидацию, и вы сразу видите, какие сервисы нужно поправить. Это дешевле, чем ловить расхождения уже на интеграции клиента и сервера.
Ошибки надо искать там, где они дешевле всего. Когда у вас есть OpenAPI, большую часть несовпадений можно поймать до того, как кто-то написал бизнес-логику и UI.
Начните с валидации спецификации: битые ссылки на схемы, несовместимые типы (например, string вместо integer), забытые обязательные поля, ошибки в oneOf/anyOf. Важно проверять не только структуру, но и ограничения: format, minLength, minimum, перечисления.
Затем проверьте примеры. Частая проблема: examples выглядят правдоподобно, но не проходят схему. Например, в примере дата "12/31/2026", а в схеме заявлен format: date-time, или status содержит значение, которого нет в enum. На таких мелочах ломается ранняя интеграция.
Полезный минимум проверок до разработки:
code, message, details);Отдельно подумайте о совместимости версий. Самые болезненные изменения - удаление полей, переименование, смена типа или смысла. Безопаснее добавлять новые поля и эндпоинты, чем менять существующие.
Чтобы изменения не превращались в сюрпризы, заведите короткий changelog и правила релиза: что считается breaking change, как версионируются эндпоинты, как долго живет старый контракт. В TakProsto для этого удобно использовать Planning mode и снапшоты: можно зафиксировать версию, сравнить изменения и быстро откатиться, если решение оказалось спорным.
Самая обидная ситуация: OpenAPI выглядит аккуратно и проходит валидацию, но в реальной работе все равно начинаются сюрпризы. Обычно проблема не в синтаксисе, а в том, что контракт не зафиксировал ограничения и примеры.
Типичная ловушка - «вход любой, потом разберемся». В спеке есть email: string, но нет формата, длины и правил. В итоге кто-то отправляет пустую строку, кто-то 10 000 символов, а кто-то email с пробелами. Контракт должен защищать и клиента, и сервер: minLength, maxLength, pattern, enum, ограничения для чисел и понятные сообщения об ошибках.
Вторая боль - разные форматы в разных ручках. Сегодня дата приходит как 2026-01-20, завтра как 20.01.2026, а деньги то в копейках amount: 19900, то в рублях amount: 199.00. Это почти гарантированно приводит к багам на фронте и в интеграциях. Лучше один формат на весь API и явное описание: дата только ISO 8601, деньги только целым числом в минимальной валютной единице.
Еще одна проблема - «200 всегда». Создание ресурса с 200 вместо 201, удаление без 204, конфликты без 409 - клиенту сложнее строить логику и обрабатывать ошибки. То же касается 400/404: они должны быть предсказуемыми и с единым телом ошибки.
Мелочь, которая дорого стоит: разные названия одного и того же. userId, id, user_id быстро плодятся, и команды начинают спорить о смысле каждого поля. Выберите стиль (camelCase или snake_case) и держите его везде.
И наконец, слишком ранняя генерация кода. Если OpenAPI уже превратили в сервер, а сценарии и примеры не согласовали, потом приходится ломать контракт или городить костыли.
Перед генерацией полезно быстро проверить:
Перед тем как писать обработчики и лезть в базу, потратьте 15 минут на контракт. Это почти всегда дешевле поправить в OpenAPI, чем потом в клиенте, тестах и миграциях.
Проверьте три вещи.
У каждой ручки должно быть понятное назначение, перечислены параметры (path/query/headers/body) и указаны коды ответов. Если везде только 200, вы уже пропускаете реальность: 400, 401, 403, 404, 409, 422, 500.
Схемы данных: обязательные поля отмечены явно, а поведение с лишними полями определено (запрещаете, игнорируете или сохраняете). Если это не зафиксировать, один клиент начнет отправлять «лишнее», а сервер начнет падать или молча терять данные.
Единый формат ошибок: договоритесь о структуре (например, code, message, details, requestId) и о списке кодов, понятных и фронту, и бэку.
Для быстрых проверок достаточно малого набора примеров: для ключевых ручек иметь успешный ответ и типовую ошибку. Примеры должны совпадать со схемами (типы, nullable, даты, enum) и выглядеть как реальные данные.
Последний шаг - прогоните контрактные проверки и зафиксируйте версию спецификации. Должно быть понятно, с какой версией работают моки и генерация обвязки. В TakProsto удобно держать это как артефакт проекта: обновили OpenAPI, сделали снапшот, сравнили изменения и при необходимости откатились.
Представим мини-сервис заявок: пользователь создает заявку, потом проверяет ее статус, а оператор видит список. Важно не писать эндпоинты «на глаз», а сначала согласовать контракт.
Вы проговариваете требования и сразу добавляете ограничения и примеры. Типичный диалог:
Из этого получается спецификация: эндпоинты POST /requests, GET /requests/{id}, GET /requests, схемы RequestCreate/Request/RequestList, ограничения (required, maxLength), enum для статусов.
По контракту поднимаются мок-ответы. Клиентская часть уже может отправлять создание заявки с примером тела, получать статус и проверять отображение, строить список с пагинацией.
На этом этапе часто всплывают несовпадения: нужен ли статус canceled, как выглядит поле в ответе (createdAt или created_at), строка это или дата, что именно означает «список» (offset/limit или cursor).
По спецификации генерируется серверная обвязка: маршруты, модели, валидация входных данных. Дальше вы пишете только бизнес-логику.
Плюс заметен сразу: вместо цепочки багов «клиент ждет одно, сервер отдает другое» вы делаете одну правку в контракте (например, добавляете canceled в enum и уточняете формат даты), обновляете моки и каркас, и команда синхронно едет дальше.
Чтобы подход прижился, сделайте его привычкой команды. Начните с малого: один сервис или один новый эндпоинт, короткий цикл и понятные правила обновления.
Соберите первую версию контракта и заморозьте ее на небольшой отрезок, например на 2-3 дня. Это не запрет на изменения, а способ собрать вопросы и правки, а потом внести их одним пакетом, не ломая всех каждый час.
Дальше оформите мок-ответы для главных сценариев: успешный результат, типовые ошибки валидации, отсутствие прав, не найдено. Моки быстро показывают, хватает ли полей, правильно ли выбраны статусы и понятно ли клиенту, что делать при ошибке.
Затем соберите каркас сервера и заранее отметьте места для ручной логики: проверки, работа с БД, интеграции, бизнес-правила. Так вы не спорите о формате данных во время реализации, а занимаетесь тем, ради чего и пишется код.
Закрепите простое правило: изменения сначала в OpenAPI, потом в код. Если продукт решил добавить поле comment в ответ, сначала меняете контракт и моки, согласуете их, и только после этого обновляете реализацию и клиента.
Минимальный ритм, который обычно работает: день 1 - черновик контракта и список открытых вопросов; день 2 - короткая заморозка и моки для 3-5 ключевых сценариев; день 3 - генерация каркаса и старт бизнес-логики, все правки через контракт.
Если хочется ускорить старт, можно попробовать собрать OpenAPI и моки из диалога в TakProsto (takprosto.ai): в Planning mode удобно разложить сценарии и правила, а затем быстро получить спецификацию и перейти к реализации с уже согласованными границами.
Контракт фиксирует, что именно считается «правильным» запросом и ответом: названия полей, типы, форматы дат, коды статусов, правила ошибок. Это резко снижает риск, что фронтенд и бэкенд сделают одно и то же по-разному и выяснят это только на интеграции.
Вначале опишите границы сервиса, ключевые сущности и 5–7 главных сценариев. Затем зафиксируйте соглашения: версию API, нейминг полей, формат дат, пагинацию, правила ошибок и авторизацию. И только после этого просите собрать OpenAPI с примерами запросов и ответов на каждый сценарий, включая ошибки.
Минимально нужны операции (метод, путь, параметры, тело запроса), ответы (коды, схемы, примеры), схемы данных (типы, обязательность, ограничения), описание безопасности и единый формат ошибок. Если хоть по одному эндпоинту непонятно, что вернется при типовых ошибках, значит контракт еще сырой.
Лучше выбрать один стандарт на все API и держаться его везде, иначе интеграции постоянно будут ломаться на мелочах. Обычно удобно использовать ISO 8601 для дат строкой, единый стиль названий полей (например, camelCase) и один формат пагинации (limit/offset или cursor) для большинства списков.
Единый формат ошибки делает обработку предсказуемой для клиента и упрощает поддержку. Практичный вариант: code для машинной логики, message для текста, details для полей и причин, плюс requestId или traceId, чтобы быстро находить запрос в логах.
Для создания и других критичных операций: клиент может повторить запрос из‑за таймаута или ретраев, и без идемпотентности вы получите дубли. Простое правило — принимать Idempotency-Key и на один ключ возвращать один и тот же результат в оговоренный период.
Моки позволяют фронтенду и тестированию начать работу без готового бэкенда и быстро увидеть, где контракт неудобный или неполный. Достаточно покрыть успешный ответ, пустой результат, отсутствие необязательных полей и типовые ошибки вроде 400, 401/403 и 404, чтобы поймать большую часть несостыковок заранее.
Сначала валидируйте саму спецификацию и все примеры на соответствие схемам: типы, форматы дат, enum-значения, обязательные поля. Затем проверьте, что коды ответов соответствуют действиям (например, 201 для создания) и что ошибки единообразны по структуре.
Меняйте сначала OpenAPI, а уже потом код и моки, чтобы у команды был один источник правды. Ручные правки в сгенерированных файлах лучше избегать, иначе быстро теряется понимание, что считается актуальным контрактом.
В TakProsto удобно сначала обсудить API в чате и получить черновик спецификации, а затем в Planning mode зафиксировать правила и спорные вопросы. Дальше можно перейти к мокам и реализации на типичном стеке платформы: веб на React, бэкенд на Go с PostgreSQL, сохранив контракт как основу для генерации обвязки и проверок.