Почему документация API — это не «ну откроешь код и разберёшься»
Каждый раз, когда на проекте появляется новый разработчик, QA или аналитик, происходит один и тот же ритуал: человек просит «дайте доку на API», а в ответ ему шлют ссылку на Confluence 2019 года, где половина эндпоинтов уже удалена, вторая половина переименована, а третьей никогда не существовало. Дальше — поход к бекендерам, бутылка пива и устные предания.
Если вам знакомо это чувство — поздравляю, вы пришли в правильный пост. Сегодня разбираемся, чем Swagger отличается от OpenAPI, почему их постоянно путают, как писать спецификацию API, которую читают не из-под палки, и при чём тут системные аналитики.
Swagger vs OpenAPI: кто кого породил и почему все путаются
Если коротко — OpenAPI это стандарт, а Swagger это набор инструментов. Но объяснять коротко — это не к нам.
Swagger — изначально проект Тони Тэма (2011), спецификация для описания REST API в формате JSON/YAML плюс набор инструментов вокруг неё (Swagger UI, Swagger Editor, Swagger Codegen).
OpenAPI Specification (OAS) — открытый стандарт, в который в 2015 году SmartBear передал Swagger 2.0 в ведение OpenAPI Initiative (Linux Foundation). С этого момента сам формат спецификации называется OpenAPI, а инструменты вокруг него остались под брендом Swagger.
То есть Swagger 2.0 = OpenAPI 2.0, а начиная с 2017 года актуальны OpenAPI 3.0 и OpenAPI 3.1 (2021). Когда коллега говорит «пришли мне сваггер», он на 99% имеет в виду YAML/JSON файл спецификации OpenAPI, а не конкретный инструмент (и на 1% — Swagger UI, потому что для многих «сваггер» = «та красивая страничка с кнопочкой Try it out»).
Swagger 2.0 vs OpenAPI 3.0: что поменялось
| Фича | Swagger 2.0 | OpenAPI 3.0/3.1 |
|---|---|---|
| Год | 2014 | 2017 / 2021 |
| Хосты/схемы | host + basePath + schemes | Массив servers с переменными |
| Тело запроса | in: body параметр | Отдельная секция requestBody |
| Несколько content-type | Костыли | content с ключами по MIME |
| Компоненты | definitions | components (schemas, responses, parameters, examples, securitySchemes) |
| Callbacks / webhooks | Нет | Есть (3.1) |
| JSON Schema | Не полностью совместим | Полная совместимость (3.1) |
| OAuth 2.0 flows | Устаревшие названия | Современные (authorizationCode, clientCredentials) |
Если вы сейчас начинаете новый проект на Swagger 2.0 — остановитесь и перейдите на OpenAPI 3.1. Единственная причина оставаться на 2.0 — legacy, который «мы потом перепишем» (спойлер: никогда).
Зачем вообще писать OpenAPI-спецификацию
Кажется очевидным, но давайте перечислим, потому что на проектах до сих пор встречаются «договоримся на созвоне».
- Контракт между командами. Бэкенд, фронтенд и мобильные разработчики могут параллельно работать по одной и той же спецификации, не дожидаясь, пока API «родится».
- Автогенерация клиентов и серверных заглушек. OpenAPI Generator умеет делать клиенты на 50+ языках и мок-серверы для QA.
- Автоматические тесты. Dredd, Schemathesis, Postman — все умеют читать OpenAPI и гонять запросы против живого API.
- Документация для людей. Swagger UI, Redoc, Stoplight Elements превращают YAML в читаемый сайт с кнопкой «попробовать».
- Валидация на бою. API Gateway (Kong, AWS API Gateway, Azure APIM) умеют валидировать запросы прямо по вашей спеке.
И самое главное — спека работает как источник истины. Когда менеджер говорит «а у нас в API есть поле X?», вы не открываете код — вы открываете один YAML и там всё написано. Если, конечно, его не забыли обновить (но это уже вопрос дисциплины, а не формата).
Анатомия OpenAPI-документа
OpenAPI-спецификация — это один YAML или JSON файл. YAML предпочтительнее: он читабельнее и комментарии поддерживает. Разберём основные секции.
openapi: 3.1.0info: title: Pet Store API version: 1.2.0 description: API магазина домашних животныхservers: - url: https://api.petstore.com/v1 description: Production - url: https://staging.api.petstore.com/v1 description: Stagingpaths: /pets: get: summary: Получить список питомцев operationId: listPets tags: [pets] parameters: - name: limit in: query schema: type: integer maximum: 100 default: 20 responses: '200': description: Успешный ответ content: application/json: schema: $ref: '#/components/schemas/PetList'components: schemas: Pet: type: object required: [id, name] properties: id: type: integer format: int64 name: type: string example: Барсик status: type: string enum: [available, pending, sold] PetList: type: array items: $ref: '#/components/schemas/Pet' securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWTsecurity: - bearerAuth: []Построчно по секциям:
openapi— версия стандарта. Пишите3.1.0, если нет веской причины иначе.info— метаданные: название, версия, описание, контакты, лицензия. Версия тут — это версия API, а не спецификации.servers— список окружений. Swagger 2.0 умел только один хост, в 3.х их можно сколько угодно, с переменными ({tenant}.api.example.com).paths— сами эндпоинты. Каждый путь содержит методы (get,post,put,patch,delete) со своими параметрами и ответами.components— переиспользуемые куски: схемы данных, ответы, параметры, примеры, схемы безопасности. Всё, что ссылается через$ref.security— какая авторизация применяется глобально (можно переопределить на уровне операции).
Правила именования эндпоинтов — отдельная большая тема, у меня про это есть пост про правила названий endpoint. В OpenAPI эти правила никуда не деваются, просто теперь они формализованы в YAML.
На диаграмме видно, что OpenAPI-файл — это не просто документ для чтения, а корневой артефакт всей API-экосистемы. Из него одним источником получаются документация, клиентские библиотеки, моки для QA, автоматические тесты контракта и правила для API Gateway. Поэтому его место — в Git, рядом с кодом, с ревью через Pull Request.
Design-first vs Code-first: как писать спеку
Два подхода, вечная религиозная война.
Design-first
Сначала пишете YAML, потом по нему пишется код. Обычно — это зона ответственности аналитика или архитектора.
Плюсы: API проектируется осознанно, команды договариваются до кода, фронтенд и бекенд работают параллельно. Минусы: нужен человек, который умеет писать OpenAPI (или готов научиться), и дисциплина — спеку надо держать в актуальном состоянии.
Code-first
Сначала пишется код с аннотациями (Springdoc для Java, drf-spectacular для Python, FastAPI из коробки), а YAML генерируется из кода при сборке.
Плюсы: нулевой шанс разъехаться с реальностью, разработчикам удобнее. Минусы: API проектируется «по ходу», аналитик часто узнаёт про новый эндпоинт постфактум, качество документации зависит от того, насколько разработчик любит писать комменты.
Личное мнение: если у вас в команде есть сильный аналитик или архитектор — используйте design-first. Если API делается небольшой командой и меняется каждые три дня — code-first честнее. Это не серебряная пуля, выбор зависит от зрелости процессов.
Типичные ошибки в OpenAPI-спецификациях
За годы ревью чужих спек я собрал топ ошибок, которые встречаю почти в каждом проекте.
1. Нет примеров
Схема type: string формально валидна, но бесполезна. Всегда добавляйте example или examples — особенно для сложных объектов. Читатель должен увидеть не абстракцию, а живой кусочек JSON.
2. Всё в одном файле на 5000 строк
OpenAPI 3.х поддерживает $ref на внешние файлы. Разносите схемы по components/schemas/*.yaml, эндпоинты — по тегам. Один гигантский файл невозможно ревьюить в Pull Request.
3. Описания вида «get pets»
summary: Get pets — это не описание, это копипаст операции. Пишите, зачем этот эндпоинт нужен бизнесу: «Возвращает список питомцев, доступных к продаже, отфильтрованных по статусу и породе. Используется на главной странице каталога».
4. Размытые коды ответов
Если у вас в спеке только 200 — вы обманываете пользователя API. Как минимум опишите 400 (валидация), 401 (неавторизован), 403 (нет прав), 404 (не найдено), 500 (всё сломалось). Идеально — с единой структурой ошибки через components/schemas/Error.
5. Нет версионирования
API эволюционирует. Закладывайте версию либо в URL (/v1/pets), либо в заголовок. И фиксируйте мажорные изменения в info.version, чтобы клиенты понимали, когда им пора обновляться.
6. Лишняя авторизация или её отсутствие
Если 90% эндпоинтов требуют JWT — опишите security глобально, а публичные эндпоинты переопределите как security: []. И наоборот. Про саму авторизацию у меня есть отдельный пост про OAuth и JWT в REST API.
Инструменты вокруг OpenAPI
Экосистема огромна, но ядро — несколько инструментов, которые стоит знать каждому, кто работает с API.
| Инструмент | Назначение | Когда использовать |
|---|---|---|
| Swagger Editor | Онлайн-редактор YAML с валидацией | Быстро набросать или отредактировать спеку |
| Swagger UI | HTML-страница из YAML с «Try it out» | Документация для разработчиков |
| Redoc | Альтернатива Swagger UI, больше для публичной доки | Когда документация ориентирована на внешних клиентов |
| Stoplight Studio | GUI-редактор с Git-интеграцией | Design-first командная работа |
| OpenAPI Generator | Генерация клиентов и серверных заглушек | Когда у вас SDK на нескольких языках |
| Prism | Мок-сервер из YAML | QA тестирует до того, как API готов |
| Spectral | Линтер для OpenAPI | Соблюдение стандартов компании в CI |
| Schemathesis | Property-based тесты по спеке | Автоматический fuzz-тестинг API |
Минимальный рабочий набор для команды: Swagger UI (доку показать), Spectral (чтобы спека не деградировала), Prism (QA не ждёт бэкенд). Остальное — по вкусу.
Роль системного аналитика: где мы во всём этом
Если вы системный аналитик и дочитали до этого места — у меня для вас хорошая новость. OpenAPI — это как раз тот артефакт, где роль аналитика видна невооружённым глазом. Вы отвечаете за:
- Проектирование ресурсов и операций (что вообще будет в API).
- Формулировки summary и description человеческим языком (разработчик напишет «creates pet», вы напишете почему и зачем).
- Примеры запросов и ответов, покрывающие бизнес-кейсы, а не только happy path.
- Коды ошибок и их описания — обычно бэкенд помнит только 200 и 500.
- Версионирование и стратегию обратной совместимости.
Фактически аналитик превращается из «человека, который пишет ТЗ в Confluence» в соавтора кода. Это намного ценнее и для проекта, и для вашей рыночной стоимости.
Чеклист хорошей OpenAPI-спецификации
- Версия OpenAPI
3.1.0(или 3.0.x, если тулчейн не подтянулся). - Есть
info.title,info.version,info.description. - Все эндпоинты имеют
summaryи осмысленныйdescription. - Все операции имеют уникальный
operationId. - Для каждой операции описаны коды ответов минимум 2xx, 4xx, 5xx.
- Все схемы вынесены в
components/schemasи переиспользуются через$ref. - Есть примеры (
example/examples) для сложных объектов. - Авторизация описана в
components/securitySchemesи применяется черезsecurity. - Файл прогоняется через Spectral без критичных ошибок.
- Спека лежит в Git рядом с кодом, изменения идут через Pull Request.
Заключение
OpenAPI — это не «ещё один YAML, который все забудут обновить через месяц». Это контракт между людьми и машинами, где люди договариваются, а машины проверяют, что договор соблюдается. Swagger — бренд инструментов вокруг этого контракта, и путать их с самим стандартом не страшно, пока вы помните, что «пришли мне сваггер» почти всегда означает «пришли мне YAML».
PS. Если после прочтения вы открыли свой рабочий API и поняли, что там задокументирован только /health — не расстраивайтесь. У всех так было. Начните с одного эндпоинта, добавьте примеры, покажите коллегам Swagger UI — и через пару месяцев у вас будет та самая документация, которую действительно читают.