Документация: OpenAPI и Swagger
Почему документация — не приятный бонус, а контракт, без которого API не существует для остального мира.
OpenAPI Specification — это машинночитаемое описание REST API в формате YAML или JSON: какие есть эндпоинты, методы, параметры, тела запросов и форматы ответов.
Можно написать идеальный API: правильные существительные в URI, корректные статусы, аккуратные ошибки. Но если о нём знаете только вы, его не существует. Другой разработчик в команде не угадает, что POST /orders требует поле customerId, а в ответ может прийти 409 Conflict. Внешний интегратор не поймёт, как выглядит объект заказа. Документация — это контракт: формальное обещание, что API ведёт себя так, как написано. И как у любого контракта, у неё должна быть единая, проверяемая форма.
Зачем нужна машинночитаемая спецификация
Текстовая документация в вики устаревает в тот же день, когда её написали. Кто-то меняет код, забывает поправить страницу — и вот уже описание врёт. OpenAPI решает это иначе: спецификация — структурированный документ, который понимают не только люди, но и инструменты. Из одного файла можно автоматически сгенерировать красивую страницу документации, поднять мок-сервер, создать клиентскую библиотеку на любом языке и проверить, что реальные ответы сервера соответствуют обещанному формату.
Исторически проект назывался Swagger. В 2015 году спецификацию передали в OpenAPI Initiative, и сам язык описания переименовали в OpenAPI Specification (OAS). Имя «Swagger» осталось за линейкой инструментов: Swagger UI, Swagger Editor, Swagger Codegen. Поэтому фразы «сваггер нашего API» и «openapi-спека» обычно означают одно и то же.
Структура спецификации
Файл OpenAPI состоит из нескольких ключевых разделов. На верхнем уровне — метаданные (info), список серверов (servers), описание путей (paths) и переиспользуемые компоненты (components). Внутри каждого пути перечислены HTTP-методы, а внутри метода — параметры, тело запроса и возможные ответы.
openapi: 3.0.3
info:
title: Orders API
version: 1.0.0
servers:
- url: https://api.example.com/v1
paths:
/orders/{orderId}:
get:
summary: Получить заказ по идентификатору
parameters:
- name: orderId
in: path
required: true
schema:
type: integer
responses:
'200':
description: Заказ найден
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
'404':
description: Заказ не найден
components:
schemas:
Order:
type: object
required: [id, status, total]
properties:
id:
type: integer
status:
type: string
enum: [new, paid, shipped]
total:
type: number
Разберём по частям. В paths описан эндпоинт /orders/{orderId} с методом get. parameters объявляет параметр пути orderId типа integer. responses перечисляет, что может вернуть сервер: 200 с телом-объектом Order или 404. Само описание объекта вынесено в components/schemas и подключается ссылкой $ref. Это даёт переиспользование: одну схему Order можно ссылаться из десятка эндпоинтов, не дублируя поля.
requestBody для записи
Для методов POST и PUT добавляется секция requestBody — она описывает тело запроса так же, как ответ описывает тело отдачи:
post:
summary: Создать заказ
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/OrderInput'
responses:
'201':
description: Заказ создан
Swagger UI и Redoc
Сам по себе YAML-файл читать неудобно. Поэтому поверх него запускают рендереры. Swagger UI превращает спецификацию в интерактивную страницу, где каждый эндпоинт можно развернуть и нажать «Try it out» — отправить настоящий запрос прямо из браузера и увидеть ответ. Redoc делает упор на чистую, читаемую документацию в три колонки: навигация, описание, примеры. Оба берут на вход один и тот же файл openapi.yaml — выбор между ними чисто эстетический.
Design-first против code-first
Есть два подхода к тому, откуда берётся спецификация. При code-first (генерация из кода) вы пишете контроллеры, развешиваете аннотации, а фреймворк собирает openapi.yaml автоматически. Быстро на старте, но спека отстаёт от обсуждения дизайна — её видно только после написания кода.
При design-first (он же spec-first) спецификацию пишут первой, до единой строчки реализации. Команда обсуждает контракт, фронтенд и бэкенд договариваются о формате, затем параллельно: бэкенд реализует, фронтенд работает по моку. Спека становится источником истины, а не побочным продуктом.
| Критерий | Code-first | Design-first |
| Старт | быстрее | медленнее |
| Источник истины | код | спецификация |
| Параллельная работа команд | сложнее | проще (мок по спеке) |
| Риск рассинхрона | ниже | выше, нужна валидация |
Что даёт спецификация
Готовый openapi.yaml — это не документ, а актив, который умножается инструментами:
- Моки. Мок-сервер (например, Prism) поднимает фейковый API по спеке — фронтенд начинает работу, пока бэкенд ещё пишется.
- Кодген клиентов. Из спеки генерируются типизированные SDK на TypeScript, Python, Go — без ручного написания обёрток над HTTP.
- Валидация. Контрактные тесты сверяют реальные ответы сервера со схемами из спеки — рассинхрон ловится автоматически.
Как работает под капотом
OpenAPI опирается на JSON Schema — стандарт описания структуры данных. Когда вы пишете type: object с properties и required, вы фактически декларируете JSON Schema для тела. Валидатор берёт реальный JSON-ответ и рекурсивно проверяет: есть ли обязательные поля, совпадают ли типы, входит ли значение в enum. Ссылки $ref — это указатели внутри документа (или на внешний файл), которые инструмент разворачивает перед обработкой, собирая плоское дерево схем. Именно поэтому спека машинночитаема: за каждым словом стоит формальная грамматика, а не свободный текст.
Частые ошибки
- Документация отдельно от кода. Спека лежит в вики и не проверяется в CI — она устаревает молча. Храните
openapi.yamlв репозитории и валидируйте. - Дублирование вместо
$ref. Описывать объектOrderзаново в каждом ответе — путь к рассинхрону. Выносите вcomponents/schemas. - Только happy path. Описан
200, но забыты400,404,401. Клиент не знает, как обрабатывать ошибки. - Путаница версий. Смешивание Swagger 2.0 и OpenAPI 3.x синтаксиса — инструменты падают. Зафиксируйте версию в поле
openapi.
Итоги
- OpenAPI (бывший Swagger) — машинночитаемый контракт REST API в YAML/JSON.
- Ключевые разделы:
paths, методы,parameters,requestBody,responses,components/schemas. - Swagger UI даёт интерактивную страницу, Redoc — чистую читаемую документацию из той же спеки.
- Design-first делает спеку источником истины; code-first быстрее, но рискует рассинхроном.
- Из спеки рождаются моки, типизированные клиенты и контрактная валидация — документация становится активом.