Как определить права на манипуляции с ресурсами для разных пользователей REST-приложения в спецификации OpenAPI: пример аутентификации с JWT-токеном для микросервисной системы интернет-магазина.
Проектирование REST API
Продолжим проектирование микросервисной системы интернет-магазина из прошлой статьи и составим спецификацию OpenAPI для REST-приложения, которое принимает запросы с клиента и направляет их к разным микросервисам, реализуя паттерн API Gateway. Напомню, проектируемая система предназначена обслуживания запросов следующих пользователей:
- Покупатель может просматривать товары, добавлять их в корзину и покупать товары, делая заказы. Также покупателю доступны функции управления своими заказами (создать, изменить, отменить) и манипулирования составом корзины (добавить товар, удалить товар, изменить количество товара).
- Менеджер интернет-магазина отвечает за управление товарами и поставщиками (создать, изменить, удалить). Также ему доступен просмотр активных заказов и просмотр отчетов по выполненным заказам согласно заданным параметрам фильтрации.
- Оператор склада изменяет состояние заказа, поскольку управляет упаковкой товаров в заказы.

При проектировании REST API важно помнить принцип работы этого архитектурного стиля построения выб-приложения. По сути, методы HTTP-запросов, которые направляет клиент на сервер для доступа к ресурсу можно представить в виде штекеров (коннекторов) для соединения с определенными розетками. Как я уже отмечала здесь,
Маршрут (Route) — это URL-адрес, который направляет запрос к определенным конечным точкам с помощью HTTP-методов. Маршрут может иметь несколько конечных точек. Конечная точка (Endpoint) — это непосредственно обращение к маршруту конкретным HTTP-методом, чтобы выполнить определенную задачу и вернуть данные с сервера клиенту.

А за розеткой, т.е. маршрутом, скрывается класс, таблица БД или другое материализованное представление для работы с сущностью домена, т.е. операций с данными. В коде такое сопоставление маршрута с функцией обработки данных выполняется, как правило, средствами специализированных фреймворков. Например, для Python есть фреймворк Flask API, пример использования которого я описывала здесь. Flask API предоставляет декорированный метод @route() для реализации конечных точек, позволяя обратиться к маршруту указанными HTTP-методами, чтобы выполнять необходимые манипуляции с данными.

Возвращаясь к рассматриваемому кейсу интернет-магазина, составим перечень сущностей домена, которые будут скрываться за маршрутами веб-приложения.
| Ресурс (Сущность) | Поле | Смысл поля | Тип данных |
| Product (Товар) | id | Идентификатор товара | integer |
| name | Название товара | string | |
| category | Категория товара | string | |
| provider | Поставщик товара | object | |
| price | Стоимость товара | number | |
| quantity | Количество единиц товара | integer | |
| Provider (Поставщик) | id | Идентификатор поставщика | integer |
| name | Название поставщика | string | |
| INN | ИНН поставщика | string | |
| site | Сайт поставщика | string | |
| phone | Телефон поставщика | string | |
| address | Адрес поставщика | string | |
| Order (Заказ) | id | Идентификатор заказа | integer |
| start_date | Дата и время создания заказа | string, т.к. в JSON нет типа данных для даты и времени. Указать, что это дата можно через format data | |
| state | Состояние заказа (новый, принят, найден, подтвержден, собран, оплачен, отменен) | string | |
| items | Массив товаров, добавленных в заказ, с указанием количества каждого товара | object | |
| sum | Сумма заказа | number | |
| Item (Товар в корзине) | id | Идентификатор товара в корзине | |
| item | Товар, добавленный в корзину | object | |
| quantity | Количество единиц товара | integer |
Далее составим перечень вариантов использования (ВИ), сопоставив их с маршрутами и конечными точками, т.е. методами HTTP-запросов, которые будут отправляться к этим URL-адресам. Также сразу отметим необходимость аутентификации для доступа к тем или иным данным посредством HTTP-запросов.
| Актор | Use Case (ВИ) | Маршрут | Конечная точка (HTTP-метод) | Аутентификация |
| · Менеджер
· Покупатель |
UC-1. Посмотреть каталог товаров | /product | GET | Не нужна |
| UC-2. Найти товар | /product | GET с параметрами фильтрации | Не нужна | |
| Менеджер | UC-3. Добавить товар | /product | POST | |
| · Менеджер
· Покупатель |
UC-4. Посмотреть товар | /product/{id} | GET | Не нужна |
| Менеджер | UC-6. Изменить товар | /product/{id} | PUT | Нужна |
| Менеджер | UC-5. Удалить товар | /product/{id} | DELETE | Нужна |
| · Менеджер
· Покупатель |
UC-7. Посмотреть список поставщиков | /provider | GET | Не нужна |
| UC-8. Найти поставщика | /provider | GET с параметрами фильтрации | Не нужна | |
| Менеджер | UC-10. Добавить поставщика | /provider | POST | Нужна |
| · Менеджер
· Покупатель |
UC-9. Посмотреть поставщика | /provider/{id} | GET | Нужна |
| Менеджер | UC-11. Изменить поставщика | /provider/{id} | PUT | Нужна |
| Менеджер | UC-12. Удалить поставщика | /provider/{id} | DELETE | Нужна |
| Менеджер | UC-12. Получить аналитический отчет по выполненным заказам | /analytics | POST (в теле запроса параметры фильтрации данных для генерации отчета) | Нужна |
| Менеджер | UC-13. Посмотреть все заказы | /order | GET | Нужна |
| · Покупатель
· Менеджер |
UC-14. Посмотреть все свои заказы | /order | GET с параметрами фильтрации | Нужна |
| · Менеджер
· Покупатель · Оператор склада |
UC-15. Найти заказ | /order | GET с параметрами фильтрации | Нужна |
| Покупатель | UC-16. Посмотреть товары в корзине | /item | GET | Нужна |
| Покупатель | UC-17. Добавить товар в корзину | /item | POST | Нужна |
| Покупатель | UC-18. Изменить количество товара в корзине | /item/{id} | PUT со значением | Нужна |
| Покупатель | UC-19. Удалить товар из корзины | /item/{id} | DELETE | Нужна |
| Покупатель | UC-20. Создать заказ | /order | POST | Нужна |
| Покупатель | UC-21. Подтвердить заказ | /order/{id} | PATCH | Нужна |
| Покупатель | UC-22. Оплатить заказ | /order/{id} | PATCH | Нужна |
| · Менеджер
· Покупатель |
UC-23. Отменить заказ | /order/{id} | PATCH | Нужна |
| Оператор склада | UC-24. Собрать заказ | /order/{id} | PATCH | Нужна |
Для аутентификации пользователя будем использовать довольно простой метод — токен на предъявителя (Bearer token) – веб-маркер JSON (JWT, JSON Web Token), который представляет собой текстовую строку, включенную в заголовок запроса. Использование токена не требует от предъявителя доказательства владения. Имея токен, можно получить доступ к ресурсам. Токен можно отозвать, и обычно он выдается на ограниченный период времени, чтобы снизить риск несанкционированного доступа к данным. Про этот и другие методы аутентификации в веб-приложениях я упоминала здесь.
В данном примере механизм JWT выбран из-за простоты, поскольку сообщение с JWT-токеном может быть реализовано любым языком программирования, поддерживающим криптографическое шифрование данных, например, алгоритмом HMAC SHA256 или RSA, сведения о котором содержатся в разделе заголовка токена, отделенного точкой от полезной нагрузки и подписи. Полезная нагрузка включает информацию о пользователе, а подпись подтверждает отправителя и гарантирует, что сообщение не было изменено во время передачи. JWT-токен с ограниченным временем жизни дает возможность регулировать длительность клиентской сессии и позволяет stateless-системе вести себя как stateful, когда ответ сервера зависит от состояния клиента. Обратной стороной достоинств JWT-токенов является их уязвимость из-за передачи в открытом виде: токен может быть расшифрован и даже изменен злоумышленником с помощью специализированных средств. Впрочем, вопросы информационной безопасности настолько глубокие и серьезные, что требуют проработки в отдельном материале, что я сделаю когда-нибудь в другой раз.
Закончив с предварительным проектированием REST API, можно перейти к детальному: разработке спецификации OpenAPI, упрощенный пример которой рассмотрен в прошлой статье.
Основы архитектуры и интеграции информационных систем
Код курса
OAIS
Ближайшая дата курса
17 ноября, 2025
Продолжительность
25 ак.часов
Стоимость обучения
56 000 руб.
Разработка спецификации OpenAPI с secure-схемой
Как обычно, формировать спецификацию будем с помощью редактора Swagger в веб-сервисе SwaggerHub, который доступен для бесплатного использования, но требует предварительной регистрации. Выбрав простой шаблон (Simple API), далее начнем разрабатывать саму спецификацию в формате YAML, внося своих акторов, маршруты и конечные точки, а также структуры данных.

Поскольку спецификация OpenAPI поддерживает вложенные структуры данных и возможность их переиспользования за счет механизма ссылок, разделим сущность домена Товар на Product, которым манипулирует менеджер, указывая количество на складе (свойство quantity) и SKU – товарную единицу номенклатуры. В спецификации OpenAPI для этого будут описаны соответствующие схемы данных. Аналогично зададим возможные значения для состояния товара, которые могут изменить разные пользователи. Например, заказ может быть отменен или самим клиентом, или менеджером магазина, если он не подтвержден / не оплачен в течении 3-х дней. Тогда схема данных для изменения состояния заказа в формате YAML будет выглядеть так:
CanceledOrder:
required:
- state
properties:
state:
type: string
enum:
- отменен клиентом
- отменен менеджером
example: отменен
Кроме того, в разделе схемы описана схема безопасности:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
Ссылка на эту схему указана в HTTP-методах обращения к ресурсам с помощью ключевого слова security:
security: - bearerAuth: []
Например, добавить новый товар в каталог может только менеджер, что описывает следующий участок спецификации OpenAPI:
paths:
/product:
post:
tags:
- manager
summary: 'Добавить товар'
operationId: addProduct
security:
- bearerAuth: []
description: Добавить новый товар в каталог
responses:
'201':
description: товар добавлен
content:
application/json:
schema:
type: object
properties:
id:
type: integer
example: 1
product:
$ref: '#/components/schemas/Product'
'400':
description: некорректный ввод
'409':
description: такой товар уже есть
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
description: Новый товар для добавления в каталог
Указание схемы безопасности означает, что для доступа к ресурсу необходимо предоставить аутентификационный токен (bearer token). Как и базовая аутентификация с прямым указанием логина и пароля, аутентификацию с bearer token следует использовать только через HTTPS (SSL). Описав эту схему безопасности в разделе components/securitySchemes, можно использовать ключевое слово security, чтобы применить эту схему к желаемой области: глобальной, т.е. ко всем конечным точкам или или конкретным операциям, как в рассмотренном примере.
Токен аутентификации передается в заголовке или в параметре запроса. Поскольку в квадратных скобках bearerAuth: [] пусто, области безопасности, т.е. конкретные требования или ограничения токена не указаны. Указав в скобках дополнительные параметры, можно регулировать разрешения на манипуляции с данными, ограничения IP-адреса и т.д. Однако, в спецификации OpenAPI области используются только с OAuth 2 и OpenID Connect, применяемыми для аутентификации через стороннего провайдера, например, ЕСИА, UML-диаграмму последовательности для которой я разбирала здесь.
Поскольку за аутентификацию и авторизацию пользователей в проектируемой системе отвечает отдельный микросервис, описываемый REST API должен давать возможность каждому пользователю ввести свои учетные данные для входа и выдать JWT-токен зарегистрированным пользователям. Для этого я добавила маршрут /login, к которому можно обратиться любой пользователь (user) путем отправки HTTP-запроса POST с передачей в теле запроса учетных данных (логина и пароля). В спецификации OpenAPI это описывает следующий участок кода:
paths:
/login:
post:
tags:
- user
summary: Вход пользователя в систему
description: Аутентификация пользователя с использованием Bearer Token (токен на предъявителя)
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
username:
type: string
description: Логин пользователя
example: anna_vichugova
password:
type: string
format: password
description: Пароль пользователя
responses:
'200':
description: Успешная аутентификация
content:
application/json:
schema:
type: object
properties:
token:
type: string
description: Bearer Token для дальнейшей аутентификации
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
'401':
description: Ошибка аутентификации, неверные учетные данные
'500':
description: Внутренняя ошибка сервера
Основы архитектуры и интеграции информационных систем
Код курса
OAIS
Ближайшая дата курса
17 ноября, 2025
Продолжительность
25 ак.часов
Стоимость обучения
56 000 руб.
Таким образом, итоговая спецификация для рассматриваемого шлюза REST API интернет-магазина выглядит следующим образом:
openapi: 3.0.0
servers:
# Added by API Auto Mocking Plugin
- description: SwaggerHub API Auto Mocking
url: https://virtserver.swaggerhub.com/VICHIGOVAANNA/Internet-shop/2.0.0
info:
description: 'Типичный интернет-магазин - демо-кейс Анны Вичуговой (расширенная версия для МСА, с JWT-аутентификацией)'
version: 2.0.0
title: API интернет-магазина
contact:
email: anna@mail.com
tags:
- name: user
description: Пользователь (все категории пользователей)
- name: manager
description: Менеджер
- name: customer
description: Покупатель
- name: operator
description: Оператор склада
paths:
/login:
get:
tags:
- user
description: Просмотр страницы ввода логина и пароля (входа в систему)
summary: Просмотр страницы ввода логина и пароля (входа в систему)
responses:
'200':
description: Успешное отображение страницы аутентификации
content:
application/json:
schema:
type: object
properties:
page:
type: object
description: Содержимое страницы для ввода логина и пароля
'404':
description: Страница не найдена
'503':
description: Сервер временно недоступен
post:
tags:
- user
summary: Вход пользователя в систему
description: Аутентификация пользователя с использованием Bearer Token (токен на предъявителя)
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
username:
type: string
description: Логин пользователя
example: anna@example.ru
password:
type: string
format: password
description: Пароль пользователя
role:
type: string
enum:
- manager
- customer
- operator
description: Роль пользователя
example: manager
responses:
'200':
description: Успешная аутентификация
content:
application/json:
schema:
type: object
properties:
token:
type: string
description: Bearer Token для дальнейшей аутентификации
example: eyJ0eXAwcvvcb1QiLCJhbGciOsdfsUzI1NiJ9.eyJpZCI6IjEzMzciLCJ1c2VybmFtZSI6ImJpem9uZSIswwwfcI6MTU5NDIwOTYwMCwicm9sZSI6InVzZXIifQ.ZvkYYnyM92xvxcvNW9_hSis7_x3_9rymsDcvcbvuOcc1I
'401':
description: Ошибка аутентификации, неверные учетные данные
'500':
description: Внутренняя ошибка сервера
/analytics:
post:
tags:
- manager
summary: Получить аналитический отчет
operationId: getAnalytics
security:
- bearerAuth: []
description: Генерация pdf-отчета по заданным фильтрам
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
client:
type: string
analysis_period:
type: string
format: date
required:
- client
- analysis_period
responses:
'200':
description: Отчет успешно сформирован
content:
application/pdf:
schema:
type: string
format: binary
'400':
description: Некорректный запрос
'500':
description: Ошибка сервера
/product:
get:
tags:
- manager
- customer
- operator
- user
summary: Посмотреть каталог товаров
operationId: viewProductCatalog
description: Параметры фильтрации товаров в каталоге для поиска
parameters:
- in: query
name: name
description: название товара для поиска
required: false
schema:
type: string
- in: query
name: category
description: категория товара для поиска
required: false
schema:
type: string
- in: query
name: provider
description: поставщик товара для поиска
required: false
schema:
type: string
- in: query
name: min_price
description: минимальная цена товара для поиска
schema:
type: integer
format: int32
minimum: 0
maximum: 100500
- in: query
name: max_price
description: максимальная цена товара для поиска
schema:
type: integer
format: int32
minimum: 0
maximum: 10005000
responses:
'200':
description: результаты поиска по запросу
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Product'
'400':
description: не верные параметры фильтрации
post:
tags:
- manager
- operator
summary: 'Добавить товар'
operationId: addProduct
security:
- bearerAuth: []
description: Добавить новый товар в каталог
responses:
'201':
description: товар добавлен
content:
application/json:
schema:
type: object
properties:
id:
type: integer
example: 1
product:
$ref: '#/components/schemas/Product'
'400':
description: некорректный ввод
'409':
description: такой товар уже есть
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
description: Новый товар для добавления в каталог
/provider:
get:
tags:
- manager
- customer
- user
summary: Посмотреть список поставщиков
operationId: viewProviderCatalog
description: Параметры фильтрации поставщиков в каталоге для поиска
parameters:
- in: query
name: name
description: название поставщика для поиска
required: false
schema:
type: string
- in: query
name: INN
description: ИНН поставщика для поиска
required: false
schema:
type: string
- in: query
name: phone
description: телефон поставщика для поиска
required: false
schema:
type: string
- in: query
name: address
description: адрес поставщика для поиска
required: false
schema:
type: string
responses:
'200':
description: результаты поиска по запросу
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Provider'
'400':
description: не верные параметры фильтрации
post:
tags:
- manager
summary: Добавить поставщика
operationId: addProvider
security:
- bearerAuth: []
description: Добавление нового поставщика в каталог
responses:
'201':
description: поставщик добавлен
content:
application/json:
schema:
type: object
properties:
id:
type: integer
example: 1
product:
$ref: '#/components/schemas/Provider'
'400':
description: некорректный ввод
'409':
description: такой поставщик уже есть
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Provider'
description: Новый поставщик для добавления в каталог
/product/{id}:
get:
tags:
- manager
- customer
- operator
summary: Посмотреть товар
operationId: viewProduct
description: Просмотр данных о конкретном товаре по его ID
parameters:
- in: path
name: id
description: ID
required: true
schema:
type: integer
format: int64
example: 1
responses:
'200':
description: Товар найден
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
'404':
description: 'Товар не найден'
put:
tags:
- manager
summary: Изменить товар
operationId: updateProduct
security:
- bearerAuth: []
description: Изменение параметров товара
parameters:
- name: id
in: path
description: ID товара, параметры которого нужно изменить
required: true
schema:
type: integer
example: 1
responses:
'200':
description: параметры товара изменены успешно
'400':
description: некорректный ввод
'404':
description: товар не найден
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
description: Измененные параметры товара
delete:
tags:
- manager
summary: 'Удалить товар'
operationId: deleteProduct
security:
- bearerAuth: []
description: Удаление товара по его идентификатору
parameters:
- name: id
in: path
description: Идентификатор товара для удаления
required: true
schema:
type: integer
example: 1
responses:
'200':
description: товар успешно удален
'404':
description: товар не найден
'500':
description: внутренняя ошибка сервера
/provider/{id}:
get:
tags:
- manager
- customer
summary: Посмотреть поставщика
operationId: viewProvider
security:
- bearerAuth: []
description: Просмотр информации о конкретном поставщике по его ID
parameters:
- in: path
name: id
description: Идентификатор поставщика
required: true
schema:
type: integer
format: int64
example: 1
responses:
'200':
description: Поставщик найден
content:
application/json:
schema:
$ref: '#/components/schemas/Provider'
'404':
description: Поставщик не найден
put:
tags:
- manager
summary: Изменить поставщика
operationId: updateProvider
security:
- bearerAuth: []
description: Изменение поставщика по его идентификатору
parameters:
- name: id
in: path
description: ID поставщика, параметры которого нужно изменить
required: true
schema:
type: integer
example: 1
responses:
'200':
description: параметры поставщика изменены успешно
'400':
description: некорректный ввод
'404':
description: поставщик не найден
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Provider'
description: Данные поставщика
delete:
tags:
- manager
summary: Удалить поставщика
operationId: deleteProvider
security:
- bearerAuth: []
description: Удаление поставщика по его идентификатору
parameters:
- name: id
in: path
description: Идентификатор поставщика для удаления
required: true
schema:
type: integer
example: 1
responses:
'200':
description: поставщик успешно удален
'404':
description: поставщик не найден
'500':
description: внутренняя ошибка сервера
/order:
get:
tags:
- manager
- customer
- operator
summary: Посмотреть заказы
operationId: viewOrders
security:
- bearerAuth: []
description: Параметры фильтрации заказов для поиска
parameters:
- in: query
name: id
description: номер заказа для поиска
required: false
schema:
type: integer
- in: query
name: start_date
description: дата создания заказа
required: false
schema:
type: string
format: date
responses:
'200':
description: результаты поиска по запросу
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Order'
'400':
description: не верные параметры фильтрации
/order/{id}:
patch:
tags:
- customer
- manager
- operator
summary: Изменить состояние заказа
security:
- bearerAuth: []
operationId: changeOrderState
description: Подтвердить, отменить или изменить статус заказа
parameters:
- name: id
in: path
description: ID заказа, статус которого надо изменить
required: true
schema:
type: integer
example: 1
responses:
'200':
description: Заказ успешно изменен
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Order'
'400':
description: Некорректный ввод
'404':
description: Заказ не найден
requestBody:
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/approvedOrder'
- $ref: '#/components/schemas/CanceledOrder'
- $ref: '#/components/schemas/CollectedOrder'
- $ref: '#/components/schemas/HoldedOrder'
discriminator:
propertyName: operationType
description: Новый статус заказа
/item:
get:
tags:
- customer
summary: Посмотреть товары в корзине
operationId: viewItem
security:
- bearerAuth: []
description: Товары в корзине
responses:
'200':
description: товары в корзине
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Item'
'500':
description: внутренняя ошибка сервера
post:
tags:
- customer
summary: Добавить товар в корзину
operationId: addItem
security:
- bearerAuth: []
responses:
'201':
description: товар добавлен
content:
application/json:
schema:
type: object
properties:
id:
type: integer
example: 1
product:
$ref: '#/components/schemas/Item'
'400':
description: некорректный ввод
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Item'
description: Товар для добавления в корзину
/item/{id}:
patch:
tags:
- customer
summary: Изменить количество товара в корзине
#operationId: updateItem
security:
- bearerAuth: []
description: Изменение количества товара по его идентификатору
parameters:
- name: id
in: path
description: ID товара, количество которого нужно изменить в корзине
required: true
schema:
type: integer
example: 1
requestBody:
content:
application/json:
schema:
type: integer
minimum: 1
maximum: 100500
description: Новое количество единиц товара в корзине
responses:
'200':
description: 'Количество товара успешно изменено'
content:
application/json:
schema:
type: object
properties:
item:
$ref: '#/components/schemas/SKU'
quantity:
type: integer
description: Количество единиц товара в корзине
example: 56
'400':
description: Некорректный ввод
'404':
description: Товар не найден в корзине
delete:
tags:
- customer
summary: Удалить товар из корзины
operationId: deleteItem
security:
- bearerAuth: []
description: Удаление товара из корзины по его идентификатору
parameters:
- name: id
in: path
description: Идентификатор товара для удаления
required: true
schema:
type: integer
example: 1
responses:
'200':
description: Товар успешно удален из корзины
'404':
description: Товар не найден
'500':
description: Внутренняя ошибка сервера
components:
schemas:
SKU:
type: object
required:
- name
- category
- provider
- price
properties:
name:
type: string
example: 'яблоки'
category:
type: string
example: 'еда'
provider:
$ref: '#/components/schemas/Provider'
price:
type: number
minimum: 0.001
maximum: 100500
example: 145.00
Product:
type: object
required:
- sku
- quantity
properties:
sku:
$ref: '#/components/schemas/SKU'
quantity:
type: integer
minimum: 1
maximum: 100500
example: 10
Provider:
required:
- name
- INN
- phone
- address
properties:
id:
type: integer
example: 1
name:
type: string
example: ООО Ромашка
INN:
type: string
example: 1234567890
site:
type: string
format: url
example: https://www.ooo-camomile.com
phone:
type: string
example: 7-495-123-45-67
address:
type: string
example: г. Москва, ул. Ленина, 123
Order:
required:
- id
- start_date
- state
- items
- sum
properties:
id:
type: integer
example: 1
start_date:
type: string
format: date
example: 2023-09-30
items:
type: array
items:
$ref: '#/components/schemas/Item'
state:
type: string
enum:
- новый
- принят
- найден
- подтвержден
- собран
- оплачен
- отменен
example: принят
sum:
type: number
example: 145.00
Item:
required:
- id
- item
- quantity
properties:
id:
type: integer
example: 1
item:
$ref: '#/components/schemas/SKU'
quantity:
type: integer
minimum: 1
maximum: 100500
example: 45
approvedOrder:
required:
- state
properties:
state:
type: string
enum:
- подтвержден
- не подтвержден
example: подтвержден
CanceledOrder:
required:
- state
properties:
state:
type: string
enum:
- отменен клиентом
- отменен менеджером
example: отменен
CollectedOrder:
required:
- state
properties:
state:
type: string
enum:
- собран
- на сборке
example: собран
HoldedOrder:
required:
- state
properties:
state:
type: string
enum:
- на оплате
- отказ от оплаты
example: на оплате
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
Помимо ранее показанных маршрутов и конечных точек с HTTP-методами со структурами данных и примерами их наполнения, в этой спецификации также показаны HTTP-ответы на запросы, подробнее о которых я писала здесь. Редактор Swagger сразу отображает UI для тестирования REST API. Также разработанная спецификация доступна по ссылке, поскольку при создании проекта для него была задана публичная видимость. Исходный код можно взять в моем Github-репозитории.

Надеюсь, что это небольшое руководство поможет начинающим аналитикам лучше понять основы проектирования REST API и принципов его документирования с помощью спецификаций OpenAPI. Про то, какие ошибки чаще всего встречаются при разработке спецификации OpenAPI и как их избежать, вы узнаете в этом материале.
Основы архитектуры и интеграции информационных систем
Код курса
OAIS
Ближайшая дата курса
17 ноября, 2025
Продолжительность
25 ак.часов
Стоимость обучения
56 000 руб.
А подробнее познакомиться со всеми рассмотренными темами, а также другими основами архитектуры и интеграции информационных систем вы сможете на моих курсах в Школе прикладного бизнес-анализа на базе нашего лицензированного учебного центра обучения и повышения квалификации системных и бизнес-аналитиков в Москве:


