Основы спецификации OpenAPI
OpenAPI Specification (OAS) — это стандартный формат для описания RESTful API.
OpenAPI Specification позволяет разработчикам определять структуру API, параметры, ответы и другую информацию в машиночитаемом виде.
Изначально OpenAPI Specification называлась Swagger Specification; позже она была передана OpenAPI Initiative и переименована в OpenAPI.
Основные функции OpenAPI Specification включают:
- Предоставление стандартизированной документации для API
- Поддержка автоматизированного тестирования API
- Генерация клиентских SDK
- Содействие разделению разработки фронтенда и бэкенда
В настоящее время OpenAPI имеет две широко используемые версии:
- OpenAPI 2.0 (ранее Swagger 2.0)
- OpenAPI 3.x (последняя стабильная версия)
Для новых проектов рекомендуется использовать OpenAPI 3.x, так как она предоставляет больше возможностей и улучшений.
Структура спецификации OpenAPI
Документы OpenAPI обычно записываются в формате YAML или JSON.
Ниже приведена базовая структура документа 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 и т. д.:
Пример
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:
Пример
- url: https://api.example.com/v1
description: Продуктивная среда
- url: https://staging-api.example.com/v1
description: Тестовая среда
3. Пути (paths)
Раздел paths определяет все конечные точки API и поддерживаемые ими методы HTTP:
Пример
/users:
get:
# Получить список пользователей
post:
# Создать нового пользователя
/users/{userId}:
get:
# Получить конкретного пользователя
put:
# Обновить пользователя
delete:
# Удалить пользователя
4. Операции (operations)
Каждый HTTP-метод в рамках пути определяет операцию API:
Пример
/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)
Параметры можно определить в нескольких местах:
Пример
- 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 и т. д.:
Пример
description: Данные пользователя
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/User'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/UserForm'
7. Ответы (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:
Пример
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:
Пример
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:
Пример
- ApiKeyAuth: []
- OAuth2: [read, write]
Создайте полный пример документа OpenAPI
Ниже приведён более полный пример API электронной коммерции:
Пример
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 поддерживает два формата:
- YAML (рекомендуется)
- JSON
Пример формата YAML
Пример
info:
title: Pet Store API
version: 1.0.0
paths:
/pets:
get:
summary: List all pets
responses:
'200':
description: Список питомцев успешно получен
Пример формата JSON
Пример
"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
- Аутентификация по пользовательскому заголовку
Ресурсы для обучения
- Официальная документация:OpenAPI Initiative
- Инструменты:
- Учебные ресурсы: