Основы спецификации OpenAPI

OpenAPI Specification (OAS) — это стандартный формат для описания RESTful API.

OpenAPI Specification позволяет разработчикам определять структуру API, параметры, ответы и другую информацию в машиночитаемом виде.

Изначально OpenAPI Specification называлась Swagger Specification; позже она была передана OpenAPI Initiative и переименована в OpenAPI.

Основные функции OpenAPI Specification включают:

  • Предоставление стандартизированной документации для API
  • Поддержка автоматизированного тестирования API
  • Генерация клиентских SDK
  • Содействие разделению разработки фронтенда и бэкенда

В настоящее время OpenAPI имеет две широко используемые версии:

  1. OpenAPI 2.0 (ранее Swagger 2.0)
  2. OpenAPI 3.x (последняя стабильная версия)

Для новых проектов рекомендуется использовать OpenAPI 3.x, так как она предоставляет больше возможностей и улучшений.

Структура спецификации OpenAPI

Документы OpenAPI обычно записываются в формате YAML или JSON.

Ниже приведена базовая структура документа OpenAPI:

Пример

openapi: 3.1.0 # Версия OpenAPI
info:
title: Пример API # Название API
description: Это пример документа API
version: 1.0.0 # Версия API
servers:
- url: https://api.example.com/v1 # Адрес сервера API
description: Продуктивная среда
  - url: https://dev-api.example.com/v1
description: Среда разработки

paths: # Определения путей API
/users: # Путь эндпоинта
get: # Метод HTTP
summary: Получить всех пользователей
description: Вернуть список всех пользователей в системе
      operationId: getUsers
      теги:
- users # Тег группы
parameters: # Параметры запроса
        - name: limit
          in: query
description: Ограничение на количество возвращаемых результатов
          schema:
            type: integer
            default: 20
responses: # Определения ответов
'200': # Код состояния HTTP
description: Успешно возвращает список пользователей
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/User'
        '400':
description: Недопустимые параметры запроса

components: # Переиспользуемые компоненты
schemas: # Определения модели данных
    User:
      type: object
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        email:
          type: string
          format: email
      required:
        - id
        - name

Подробное объяснение основных концепций OpenAPI

1. Метаданные документа (info)

Раздел info содержит базовую информацию об API, такую как title, description, version и т. д.:

Пример

info:
title: API управления пользователями
description: API для управления информацией о пользователях в системе
  version: 1.0.0
  contact:
name: Команда поддержки API
    email: [email protected]
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html

2. Информация о серверах (servers)

Раздел servers определяет список доступных серверов API:

Пример

servers:
  - url: https://api.example.com/v1
description: Продуктивная среда
  - url: https://staging-api.example.com/v1
description: Тестовая среда

3. Пути (paths)

Раздел paths определяет все конечные точки API и поддерживаемые ими методы HTTP:

Пример

paths:
  /users:
    get:
# Получить список пользователей
    post:
# Создать нового пользователя
  /users/{userId}:
    get:
# Получить конкретного пользователя
    put:
# Обновить пользователя
    delete:
# Удалить пользователя

4. Операции (operations)

Каждый HTTP-метод в рамках пути определяет операцию API:

Пример

paths:
  /users/{userId}:
    get:
summary: Получить сведения о пользователе
description: Получить подробную информацию о пользователе по ID пользователя
      operationId: getUserById
      теги:
        - users
      parameters:
        - name: userId
          in: path
          required: true
description: ID пользователя
          schema:
            type: integer
      responses:
        '200':
description: Успешно получена информация о пользователе
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '404':
description: Пользователь не существует
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

5. Параметры (parameters)

Параметры можно определить в нескольких местах:

Пример

parameters:
  - name: userId
in: path # Параметр пути
    required: true
    schema:
      type: integer
  - name: filter
in: query # Параметр запроса
    schema:
      type: string
  - name: X-API-Key
in: header # Параметр заголовка
    schema:
      type: string
  - name: trace
in: cookie # Параметр cookie
    schema:
      type: string

6. Тело запроса (requestBody)

Определите тело запроса для таких методов, как POST, PUT и т. д.:

Пример

requestBody:
description: Данные пользователя
  required: true
  content:
    application/json:
      schema:
        $ref: '#/components/schemas/User'
    application/x-www-form-urlencoded:
      schema:
        $ref: '#/components/schemas/UserForm'

7. Ответы (responses)

Определите возможные ответы для каждой операции:

Пример

responses:
  '200':
description: Операция выполнена успешно
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/SuccessResponse'
  '400':
description: Недопустимые параметры запроса
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/ErrorResponse'

8. Компоненты (components)

Раздел components используется для хранения элементов, которые можно повторно использовать во всём документе API:

Пример

components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        email:
          type: string
          format: email
        roles:
          type: array
          items:
            type: string
            enum: [admin, user, editor]
      required:
        - name
        - электронная почта
   
    Ошибка:
      type: object
      properties:
        код:
          type: integer
        сообщение:
          type: string
      required:
        - code
        - сообщение
 
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
   
    OAuth2:
      type: oauth2
      flows:
        implicit:
          authorizationUrl: https://example.com/oauth/authorize
          scopes:
read: Разрешение на чтение
write: Разрешение на запись

9. Модели данных (schemas)

Определите структуры данных, используемые в API:

Пример

schemas:
  Product:
    type: object
    properties:
      id:
        type: integer
      name:
        type: string
        maxLength: 100
      price:
        type: number
        format: float
        minimum: 0
      category:
        type: string
        enum: [electronics, books, clothing]

10. Безопасность (security)

Определите методы аутентификации и авторизации для API:

Пример

security:
  - ApiKeyAuth: []
  - OAuth2: [read, write]

Создайте полный пример документа OpenAPI

Ниже приведён более полный пример API электронной коммерции:

Пример

openapi: 3.1.0
info:
title: API электронной коммерции
description: API для управления товарами и заказами в интернет-магазине
  version: 1.0.0
  contact:
name: Команда поддержки API
    email: [email protected]
    url: https://api.example.com/support
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT

servers:
  - url: https://api.example.com/v1
description: Производственная среда
  - url: https://dev-api.example.com/v1
description: Среда разработки

теги:
  - name: products
description: Операции, связанные с товарами
  - name: orders
description: Операции, связанные с заказами
  - name: users
description: Операции, связанные с пользователями

paths:
  /products:
    get:
summary: Получить список продуктов
description: Возвращает список всех доступных продуктов с поддержкой пагинации и фильтрации
      operationId: getProducts
      теги:
        - products
      parameters:
        - name: category
          in: query
description: Фильтр по категории продукта
          schema:
            type: string
        - name: page
          in: query
description: Номер страницы
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
description: Количество элементов на странице
          schema:
            type: integer
            default: 20
      responses:
        '200':
description: Список товаров успешно получен
          content:
            application/json:
              schema:
                type: object
                properties:
                  total:
                    type: integer
                  products:
                    type: array
                    items:
                      $ref: '#/components/schemas/Product'
        '400':
description: Ошибка параметра
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
   
    post:
summary: Создать новый товар
description: Информация о создании нового товара
      operationId: createProduct
      теги:
        - products
      security:
        - ApiKeyAuth: []
        - OAuth2: [write]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProductCreate'
      responses:
        '201':
description: Товар успешно создан
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Product'
        '400':
description: Некорректные данные запроса
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
description: Неавторизован
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /products/{productId}:
    get:
summary: Получить сведения о продукте
description: Получить подробную информацию о конкретном продукте по ID
      operationId: getProductById
      теги:
        - products
      parameters:
        - name: productId
          in: path
          required: true
description: ID продукта
          schema:
            type: integer
      responses:
        '200':
description: Информация о продукте успешно получена
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Product'
        '404':
description: Продукт не найден
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
   
    put:
summary: Обновить продукт
description: Обновить информацию о конкретном продукте
      operationId: updateProduct
      теги:
        - products
      security:
        - ApiKeyAuth: []
        - OAuth2: [write]
      parameters:
        - name: productId
          in: path
          required: true
description: ID продукта
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProductUpdate'
      responses:
        '200':
description: Товар успешно обновлен
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Product'
        '400':
description: Некорректные данные запроса
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
description: Неавторизован
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
description: Продукт не найден
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
   
    delete:
summary: Удалить товар
description: Удалить конкретный товар
      operationId: deleteProduct
      теги:
        - products
      security:
        - ApiKeyAuth: []
        - OAuth2: [write]
      parameters:
        - name: productId
          in: path
          required: true
description: ID продукта
          schema:
            type: integer
      responses:
        '204':
description: Товар успешно удален
        '401':
description: Неавторизован
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
description: Продукт не найден
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /orders:
    get:
summary: Получить список заказов
description: Возвращает список всех заказов с поддержкой пагинации и фильтрации
      operationId: getOrders
      теги:
        - orders
      security:
        - ApiKeyAuth: []
        - OAuth2: [read]
      parameters:
        - name: status
          in: query
description: Фильтр по статусу заказа
          schema:
            type: string
            enum: [pending, processing, shipped, delivered, cancelled]
        - name: page
          in: query
description: Номер страницы
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
description: Количество элементов на странице
          schema:
            type: integer
            default: 20
      responses:
        '200':
description: Список заказов успешно получен
          content:
            application/json:
              schema:
                type: object
                properties:
                  total:
                    type: integer
                  orders:
                    type: array
                    items:
                      $ref: '#/components/schemas/Order'
        '401':
description: Неавторизован
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
   
    post:
summary: Создать новый заказ
description: Создать новый заказ
      operationId: createOrder
      теги:
        - orders
      security:
        - ApiKeyAuth: []
        - OAuth2: [write]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrderCreate'
      responses:
        '201':
description: Заказ успешно создан
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Order'
        '400':
description: Некорректные данные запроса
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
description: Неавторизован
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

components:
  schemas:
    Product:
      type: object
      properties:
        id:
          type: integer
          format: int64
          readOnly: true
        name:
          type: string
          maxLength: 100
        описание:
          type: string
        price:
          type: number
          format: float
          minimum: 0
        category:
          type: string
          enum: [electronics, books, clothing, food]
        inStock:
          type: boolean
          default: true
        createdAt:
          type: string
          format: date-time
          readOnly: true
        updatedAt:
          type: string
          format: date-time
          readOnly: true
      required:
        - name
        - price
        - category
   
    ProductCreate:
      type: object
      properties:
        name:
          type: string
          maxLength: 100
        описание:
          type: string
        price:
          type: number
          format: float
          minimum: 0
        category:
          type: string
          enum: [electronics, books, clothing, food]
        inStock:
          type: boolean
          default: true
      required:
        - name
        - price
        - category
   
    ProductUpdate:
      type: object
      properties:
        name:
          type: string
          maxLength: 100
        описание:
          type: string
        price:
          type: number
          format: float
          minimum: 0
        category:
          type: string
          enum: [electronics, books, clothing, food]
        inStock:
          type: boolean
   
    Order:
      type: object
      properties:
        id:
          type: integer
          format: int64
          readOnly: true
        userId:
          type: integer
          format: int64
        items:
          type: array
          items:
            $ref: '#/components/schemas/OrderItem'
        totalAmount:
          type: number
          format: float
          readOnly: true
        status:
          type: string
          enum: [pending, processing, shipped, delivered, cancelled]
          default: pending
        shippingAddress:
          $ref: '#/components/schemas/Address'
        createdAt:
          type: string
          format: date-time
          readOnly: true
        updatedAt:
          type: string
          format: date-time
          readOnly: true
      required:
        - userId
        - items
        - shippingAddress
   
    OrderCreate:
      type: object
      properties:
        userId:
          type: integer
          format: int64
        items:
          type: array
          items:
            $ref: '#/components/schemas/OrderItem'
        shippingAddress:
          $ref: '#/components/schemas/Address'
      required:
        - userId
        - items
        - shippingAddress
   
    OrderItem:
      type: object
      properties:
        productId:
          type: integer
          format: int64
        quantity:
          type: integer
          minimum: 1
          default: 1
        unitPrice:
          type: number
          format: float
          readOnly: true
      required:
        - productId
        - quantity
   
    Address:
      type: object
      properties:
        street:
          type: string
        city:
          type: string
        состояние:
          type: string
        zipCode:
          type: string
        country:
          type: string
      required:
        - street
        - city
        - state
        - zipCode
        - country
   
    Ошибка:
      type: object
      properties:
        код:
          type: integer
        сообщение:
          type: string
      required:
        - code
        - сообщение
 
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
   
    OAuth2:
      type: oauth2
      flows:
        implicit:
          authorizationUrl: https://example.com/oauth/authorize
          scopes:
read: Разрешение на чтение
write: Разрешение на запись

security:
  - ApiKeyAuth: []

Базовый синтаксис спецификации OpenAPI

Спецификация OpenAPI поддерживает два формата:

  1. YAML (рекомендуется)
  2. JSON

Пример формата YAML

Пример

openapi: 3.0.0
info:
title: Pet Store API
  version: 1.0.0
paths:
  /pets:
    get:
summary: List all pets
      responses:
        '200':
description: Список питомцев успешно получен

Пример формата JSON

Пример

"openapi": "3.0.0",
  "info": {
    "title": "API зоомагазина",
    "version": "1.0.0"
  },
  "paths": {
    "/pets": {
      "get": {
        "summary": "Список всех питомцев",
        "responses": {
          "200": {
            "description": "Список питомцев успешно получен"
          }
        }
      }
    }
  }
}

Как использовать спецификацию OpenAPI

1. Создание и редактирование документов OpenAPI

Вы можете использовать следующие инструменты для создания и редактирования документов OpenAPI:

  • Swagger Editor: онлайн-редактор с предварительным просмотром и проверкой в реальном времени
  • Stoplight Studio: инструмент визуального проектирования API
  • VS Code + OpenAPI plugin: редактирование в интегрированной среде разработки

2. Генерация документации

Спецификация OpenAPI может автоматически создавать красивую документацию API. Распространённые инструменты включают:

  • Swagger UI: генерация интерактивной документации API
  • ReDoc: предоставляет адаптивную настраиваемую документацию
  • Slate: генерация элегантной статической документации

3. Генерация кода

OpenAPI может автоматически генерировать клиентский и серверный код на нескольких языках:

  • OpenAPI Generator: поддерживает 40+ языков программирования
  • Swagger Codegen: генерация клиентского и серверного кода
  • NSwag: Генератор кода для экосистемы .NET

4. Тестирование API и мокирование

Спецификацию OpenAPI также можно использовать для:

  • Автоматизированное тестирование: Использование таких инструментов, как Postman, SoapUI
  • Мокирование API: Prism, Microcks и т. д. могут создавать макеты API на основе спецификации OpenAPI

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

1. Принципы проектирования

  • Поддерживайте единообразие именования конечных точек
  • Используйте подходящие методы HTTP и коды состояния
  • Проектируйте четкую структуру URL-путей

2. Рекомендации по документации

  • Предоставляйте подробные описания и примеры
  • Используйте теги для группировки API
  • Четко указывайте обязательные параметры

3. Стратегия управления версиями

  • Включите номер версии в URL (/v1/users)
  • Используйте заголовки запроса для указания версии (Accept: application/vnd.example.v1+json)
  • Четко указывайте информацию о версии в документе OpenAPI

Часто задаваемые вопросы

1. В чем разница между OpenAPI и Swagger?

Swagger — предшественник спецификации OpenAPI. В 2016 году спецификация Swagger была передана Linux Foundation и переименована в спецификацию OpenAPI. Сейчас "Swagger" обычно обозначает набор инструментов, созданных вокруг спецификации OpenAPI.

2. Каковы основные различия между OpenAPI 2.0 и 3.x?

OpenAPI 3.x представил множество новых возможностей, включая:

  • Улучшенное повторное использование компонентов
  • Более гибкие определения тела запроса
  • Более мощные определения безопасности
  • Улучшенная поддержка JSON Schema
  • Поддержка links и callbacks

3. Как обрабатывать аутентификацию и авторизацию?

OpenAPI поддерживает несколько механизмов безопасности:

  • API-ключи
  • Базовая аутентификация HTTP
  • OAuth2.0
  • OpenID Connect
  • Аутентификация по пользовательскому заголовку

Ресурсы для обучения

  1. Официальная документация:OpenAPI Initiative
  2. Инструменты:
  3. Учебные ресурсы:
Другие расширения