Learnly
Проектирование API/Глава 16/Урок 1

Документирование API: OpenAPI и Swagger

Документирование API: OpenAPI и Swagger

Хорошая документация, это уважение к потребителям API. Плохая документация, это когда разработчик смотрит в исходный код чтобы понять как работает твой /users эндпоинт.


Зачем документировать API

Без документации:

  • Разработчики изучают API методом проб и ошибок
  • «Живая документация» в Slack устаревает быстрее чем пишется
  • Онбординг новых членов команды занимает недели
  • Внешние партнёры не могут интегрироваться самостоятельно

С хорошей документацией:

  • Интеграция занимает часы вместо дней
  • Нет вопросов в Slack типа «а какой формат поля date?»
  • Автогенерируются клиентские SDK
  • Можно тестировать API прямо в браузере

OpenAPI Specification

OpenAPI (бывший Swagger), стандарт описания REST API в формате YAML или JSON. Это машиночитаемый контракт из которого генерируется документация, клиенты и тесты.

Базовая структура

openapi: "3.0.3"
info:
  title: Learnly API
  version: "1.0.0"
  description: API образовательной платформы Learnly

servers:
  - url: https://api.learnly.online/v1
    description: Production
  - url: https://api-staging.learnly.online/v1
    description: Staging

paths:
  /users/{id}:
    get:
      summary: Получить пользователя
      description: Возвращает данные пользователя по его ID
      tags:
        - Users
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: ID пользователя
      responses:
        '200':
          description: Пользователь найден
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '404':
          description: Пользователь не найден
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - bearerAuth: []

components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
          example: 42
        name:
          type: string
          example: "Иван Петров"
        email:
          type: string
          format: email
          example: "ivan@example.com"
        created_at:
          type: string
          format: date-time
          example: "2024-03-15T10:23:00Z"
      required:
        - id
        - name
        - email

    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              example: "NOT_FOUND"
            message:
              type: string
              example: "Пользователь не найден"

  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

Описание POST запроса с телом

  /users:
    post:
      summary: Создать пользователя
      tags:
        - Users
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - email
                - password
              properties:
                name:
                  type: string
                  example: "Иван Петров"
                  minLength: 2
                  maxLength: 100
                email:
                  type: string
                  format: email
                  example: "ivan@example.com"
                password:
                  type: string
                  format: password
                  minLength: 8
                  example: "securePass123"
            examples:
              example1:
                summary: Пример создания пользователя
                value:
                  name: "Мария Иванова"
                  email: "maria@company.com"
                  password: "myPassword123"
      responses:
        '201':
          description: Пользователь создан
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '422':
          description: Ошибки валидации
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

Swagger UI

Swagger UI превращает OpenAPI спецификацию в интерактивную документацию прямо в браузере. Разработчики могут тестировать API без Postman.

Подключение в Node.js/Express:

import swaggerUi from 'swagger-ui-express';
import YAML from 'yamljs';

const swaggerDocument = YAML.load('./openapi.yaml');

app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument, {
  customSiteTitle: 'Learnly API Docs',
  swaggerOptions: {
    persistAuthorization: true,  // сохраняет токен между запросами
  }
}));

После этого по /docs доступна полная интерактивная документация.


Лучшие практики

1. Описывай примеры, не только схемы

# Плохо, нет примеров
properties:
  status:
    type: string

# Хорошо, понятно без объяснений
properties:
  status:
    type: string
    enum: [pending, processing, shipped, delivered, cancelled]
    example: "processing"
    description: "Текущий статус заказа"

2. Группируй эндпоинты через теги

tags:
  - name: Auth
    description: Аутентификация и управление сессиями
  - name: Users
    description: Управление пользователями
  - name: Orders
    description: Создание и управление заказами

3. Описывай все коды ошибок

responses:
  '200':
    description: Успешно
  '400':
    description: Неверный запрос
  '401':
    description: Не аутентифицирован
  '403':
    description: Нет прав доступа
  '404':
    description: Ресурс не найден
  '500':
    description: Внутренняя ошибка сервера

4. Используй $ref для переиспользования

components:
  responses:
    NotFound:
      description: Ресурс не найден
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'

# Использование в любом эндпоинте:
responses:
  '404':
    $ref: '#/components/responses/NotFound'

5. Версионируй спецификацию вместе с кодом

Держи openapi.yaml рядом с кодом в репозитории. Изменения API = изменения в спецификации в том же PR. Code review включает проверку контракта.


Генерация клиентов

Одно из главных преимуществ OpenAPI, автоматическая генерация клиентских библиотек:

# TypeScript клиент
npx @openapitools/openapi-generator-cli generate \
  -i openapi.yaml \
  -g typescript-axios \
  -o ./src/api-client

# Python клиент
openapi-generator generate -i openapi.yaml -g python -o ./python-client

Клиент создаётся автоматически: типы, методы, обработка ошибок. Потребители API не пишут HTTP-запросы вручную.


Альтернативы

Инструмент Когда использовать
OpenAPI/Swagger REST API, стандарт индустрии
Postman Collections Быстрое документирование, тестирование команды
Redoc Красивая читаемая документация из OpenAPI
Stoplight Визуальный редактор OpenAPI спецификаций
GraphQL Introspection Для GraphQL API (встроенная документация)
AI-тест
1 / 6

Какую роль играет документация API в процессе интеграции и сопровождения системы?