Чтобы показать, как устроена RESTful-система, я реализовала небольшой MVP для интернет-магазина, развернув экземпляр базы данных PostgreSQL в serverless-платформе Neon, с которой взаимодействует серверное Flask-приложение, запущенное в Google Colab и тунеллированное с помощью утилиты ngrok. Техническая часть реализации подробно рассмотрена здесь, а сегодня разберем постановку задачи и проектирование этой системы.
Постановка задачи и разработка требований
В качестве наглядного примера возьмем мой традиционный кейс с интернет-магазином. Бизнес-контекст проектируемой системы описан в предыдущей статье про причинно-следственный анализ и построение карты влияния. Именно на основе этой карты влияния составим набор пользовательских историй для менеджера интернет-магазина, которому необходимо адаптировать товарный ассортимент под потребности и возможности клиентов.
В качестве бизнес-метрики возьмем эффективность товарного ассортимента как меру успешности и прибыльности набора товаров, предлагаемых магазином. Она определяет способность ассортимента удовлетворять потребности и предпочтения потребителей, а также генерировать высокий уровень продаж и прибыли. Для оценки эффективности товарного ассортимента используются различные показатели, такие как объем продаж, доля рынка, средний чек, прибыльность товаров и пр. Обычно торговые компании ищут баланс между предложением и спросом, стремясь обеспечить такое разнообразие товаров, чтобы максимизировать свою прибыль и удовлетворенность потребителей.
Для достижения высокой эффективности товарного ассортимента необходимо анализировать предпочтения потребителей, чтобы оптимизировать товарный ассортимент, добавлять популярные товары и удалять неэффективные. А поскольку товары интернет-магазин закупает у различных поставщиков, менеджеру магазина необходимо управлять товарами и поставщиками, выполняя следующие действия:
- Просматривать перечень товаров и поставщиков;
- Просматривать детали конкретного товара и конкретного поставщика;
- Добавлять новые товары и новых поставщиков;
- Изменять данные отдельных товаров и поставщиков;
- Удалять товары и поставщиков.
Также в рамках MVP рассмотрим возможность ручного управления клиентскими заказами, когда менеджер интернет-магазина может просмотреть список всех заказов, детали по отдельному заказу и изменить его состояние. Перечни товаров и поставщиков интернет-магазина являются публичной информацией, которая может быть доступна не только менеджеру, но и покупателю.
Теперь представим это в виде набора пользовательских историй и системных вариантов использования, в которых они воплощаются.
| Актор | User Story | Use Case |
| Покупатель | US-1.1 Как покупатель интернет-магазина, я хочу видеть перечень товаров, чтобы узнать подробности ассортимента (название товара, поставщик, стоимость, количество единиц в наличии) | UC 1.1 Посмотреть список товаров |
| Покупатель | US-1.2 Как покупатель интернет-магазина, я хочу видеть перечень поставщиков, чтобы узнать подробности о продавцах (название компании, телефон, емейл, адрес) | UC 1.2 Посмотреть список поставщиков |
| Менеджер | US-2.1.1 Как менеджер интернет-магазина, я хочу видеть перечень товаров с их данными (название, поставщик, стоимость, количество единиц в наличии), чтобы повысить эфективность товарного ассортимента | UC 1.1 Посмотреть список товаров |
| Менеджер | US-2.1.2 Как менеджер интернет-магазина, я хочу добавлять новый товар, задавая данные о нем (название, поставщик, стоимость, количество единиц в наличии), чтобы повысить эфективность товарного ассортимента | UC 2.1.1 Добавить товар |
| Менеджер | US-2.1.3 Как менеджер интернет-магазина, я хочу управлять конкретным товаром, изменяя его данные (название, поставщик, стоимость, количество единиц в наличии) или удаляя его, чтобы повысить эфективность товарного ассортимента | UC 2.1.2 Посмотреть товар |
| UC 2.1.3 Изменить товар | ||
| UC 2.1.4 Удалить товар | ||
| Менеджер | US-2.2.1 Как менеджер интернет-магазина, я хочу видеть перечень поставщиков с их данными (название компании, телефон, емейл, адрес), чтобы повысить повысить эфективность товарного ассортимента за счет улучшения работы с контрагентами | UC 1.2 Посмотреть список поставщиков |
| Менеджер | US-2.2.2 Как менеджер интернет-магазина, я хочу добавлять нового поставщика, задавая данные о нем (название компании, телефон, емейл, адрес), чтобы повысить эфективность товарного ассортимента | UC 2.2.1 Добавить поставщика |
| Менеджер | US-2.2.3 Как менеджер интернет-магазина, я хочу управлять конкретным поставщиком, изменяя его данные (название компании, телефон, емейл, адрес), или удаляя его, чтобы повысить повысить эфективность товарного ассортимента за счет улучшения работы с контрагентами | UC 2.2.2 Посмотреть поставщика |
| UC 2.2.3 Изменить поставщика | ||
| UC 2.2.4 Удалить поставщика | ||
| Менеджер | US-3.1 Как менеджер интернет-магазина, я хочу видеть перечень клиентских азказов, чтобы оценивать эффективность товарного ассортимента по состояниям заказов | UC 3.1 Посмотреть список заказов |
| Менеджер | US-3.2 Как менеджер интернет-магазина, я хочу вручную изменять состояние клиентского заказа, чтобы информировать клиента о его готовности | UC 3.2.1 Посмотреть заказ |
| UC 3.2.2 Изменить состояние заказ |
Разработка ТЗ на информационную систему по ГОСТ и SRS
Код курса
TTIS
Ближайшая дата курса
10 ноября, 2025
Продолжительность
22 ак.часов
Стоимость обучения
48 000 руб.
Варианты использования UC 1.1 Посмотреть список товаров и UC 1.2 Посмотреть список поставщиков доступны для всех пользователей проектируемой системы, а остальные Use Case предназначены только для пользователя с ролью Менеджер. Поэтому необходимо предусмотреть еще пару системных вариантов использования, связанных с аутентификацией пользователя. В свою очередь, аутентификации предшествует регистрация пользователя в системе. Как это реализовано, а расскажу в следующей статье, а пока составим полный реестр ВИ.
| Актор | Use Case |
| Пользователь (Покупатель, Менеджер) | UC 0 Войти в систему |
| Пользователь (Покупатель, Менеджер) | UC 0.1 Аутентификация |
| Пользователь (Покупатель, Менеджер) | UC 0.2 Зарегистрироваться |
| Пользователь (Покупатель, Менеджер) | UC 1.1 Посмотреть список товаров |
| Менеджер | UC 2.1.1 Добавить товар |
| Менеджер | UC 2.1.2 Посмотреть товар |
| Менеджер | UC 2.1.3 Изменить товар |
| Менеджер | UC 2.1.4 Удалить товар |
| Пользователь (Покупатель, Менеджер) | UC 1.2 Посмотреть список поставщиков |
| Менеджер | UC 2.2.1 Добавить поставщика |
| Менеджер | UC 2.2.2 Посмотреть поставщика |
| Менеджер | UC 2.2.3 Изменить поставщика |
| Менеджер | UC 2.2.4 Удалить поставщика |
| Менеджер | UC 3.1 Посмотреть список заказов |
| Менеджер | UC 3.2.1 Посмотреть заказ |
| Менеджер | UC 3.2.2 Изменить состояние заказа |
Визуализируем этот реестр Ви в виде UML-диаграммы Use Case. Чтобы сделать диаграмму более читаемой, исключив пересечения линий, я разделила ее на 3 по областям действия пользовательских историй.
Управление товарами визуализирует следующая диаграмма.

Эта диаграмма создана с помощью следующего PlantUML-скрипта:
@startuml
title: Управление товарами в интернет-магазине
skinparam packageStyle rectangle
actor Пользователь
actor Менеджер
actor Покупатель
Пользователь <|- :Менеджер:
Покупатель -|> :Пользователь:
rectangle Товары_Интернет_магазин {
Пользователь --> (Войти в систему)
(Зарегистрироваться) .> (Войти в систему) : extend
(Аутентификация) ..> (Войти в систему) : extend
(Добавить товар) .-> (Аутентификация) : include
Пользователь ---> (Посмотреть список товаров)
Менеджер --> (Добавить товар)
Менеджер --> (Посмотреть товар)
(Добавить товар) ..> (Посмотреть список товаров) : extend
(Посмотреть список товаров) <.. (Посмотреть товар) : extend
(Посмотреть товар) <.. (Удалить товар) : extend
(Посмотреть товар) <.. (Изменить товар) : extend
(Посмотреть товар) .> (Аутентификация): include
}
@enduml
Управление поставщиками визуализирует следующая диаграмма.

Эта диаграмма создана с помощью следующего PlantUML-скрипта:
@startuml
title: Управление поставщиками в интернет-магазине
skinparam packageStyle rectangle
actor Пользователь
actor Менеджер
actor Покупатель
Пользователь <|- :Менеджер:
Покупатель -|> :Пользователь:
rectangle Поставщики_Интернет_магазин {
Пользователь --> (Войти в систему)
(Зарегистрироваться) .> (Войти в систему) : extend
(Аутентификация) ..> (Войти в систему) : extend
(Добавить поставщика) .-> (Аутентификация) : include
Пользователь ---> (Посмотреть список поставщиков)
Менеджер --> (Добавить поставщика)
Менеджер --> (Посмотреть поставщика)
(Добавить поставщика) ..> (Посмотреть список поставщиков) : extend
(Посмотреть список поставщиков) <.. (Посмотреть поставщика) : extend
(Посмотреть поставщика) <.. (Удалить поставщика) : extend
(Посмотреть поставщика) <.. (Изменить поставщика) : extend
(Посмотреть поставщика) .> (Аутентификация): include
}
@enduml
Наконец, управление заказами визуализирует следующая диаграмма.

Эта диаграмма создана с помощью следующего PlantUML-скрипта:
@startuml
title: Управление заказами в интернет-магазине
skinparam packageStyle rectangle
actor Пользователь
actor Менеджер
actor Покупатель
Пользователь <|- :Менеджер:
Покупатель -|> :Пользователь:
rectangle Заказы_Интернет_магазин {
Пользователь --> (Войти в систему)
(Зарегистрироваться) .> (Войти в систему) : extend
(Аутентификация) ..> (Войти в систему) : extend
Менеджер ---> (Посмотреть список заказов)
Менеджер --> (Посмотреть заказ)
(Посмотреть список заказов) <.. (Посмотреть заказ) : extend
(Посмотреть заказ) <.. (Изменить заказ) : extend
(Посмотреть заказ) .> (Аутентификация): include
}
@enduml
DDD, ООП и UML для аналитика
Код курса
BUML
Ближайшая дата курса
8 декабря, 2025
Продолжительность
22 ак.часов
Стоимость обучения
48 000 руб.
Закончив на этом постановку задачи, перейдем к проектированию системы. В целях экономии времени, здесь намерено пропущен целый ряд шагов по полной спецификации требований, иначе статья превратится в книгу).
Проектирование модели данных
Чтобы гарантировать доступность управления поставщиками, товарами и заказами только для пользователей с ролью Менеджер (UC 2.1.1- UC 2.1.4, UC 2.2.1-UC 2.2.4, UC 3.1, UC 3.1.1 и UC 3.1.2), необходимо определить способ аутентификации. В рамках проектируемого MVP доступность варианта использования для конкретного актора будет основана на JWT-токене с ограниченным временем жизни. Этот токен будет выдаваться только пользователям с ролью Менеджер. Данные об этом будут храниться в системе.
Таким образом, в системе необходимы следующие сущности, которые будут материализованы в виде таблиц реляционной базы данных PostgreSQL:
| Сущность | Таблица БД | Поле | Смысл поля | Тип данных |
| Товар | product
|
id | уникальный идентификатор товара | INTEGER |
| name | название товара | VARCHAR(255) | ||
| provider | уникальный идентификатор поставщика | INTEGER | ||
| price | цена товара | |||
| quantity | количество товара на складе | INTEGER | ||
| Поставщик | provider | id | уникальный идентификатор поставщика | INTEGER |
| name | название поставщика | VARCHAR(255) | ||
| phone | контактный номер телефона поставщика | VARCHAR(255) | ||
| электронная почта поставщика | VARCHAR(255) | |||
| address | адрес поставщика | VARCHAR(255) | ||
| Заказ | orders | id | уникальный идентификатор заказа | INTEGER |
| customer | идентификатор клиента | INTEGER | ||
| state | идентификатор состояния заказа | INTEGER | ||
| delivery | идентификатор доставки | INTEGER | ||
| sum | сумма заказа | DOUBLE PRECISION | ||
| date | дата заказа | DATE | ||
| Доставка | delivery | id | уникальный идентификатор доставки | INTEGER |
| date | дата доставки | DATE | ||
| address | адрес доставки | TEXT | ||
| price | стоимость доставки | DOUBLE PRECISION | ||
| Товары в заказе | order_product | id | уникальный идентификатор товара в заказе | INTEGER |
| order | идентификатор заказа | INTEGER | ||
| product | идентификатор товара | INTEGER | ||
| quantity | количество товаров в заказе | INTEGER | ||
| Состояние заказа | order_states | id | уникальный идентификатор состояния заказа | INTEGER |
| name | название состояния заказа | VARCHAR(255) | ||
| Покупатель | customer | id | уникальный идентификатор покупателя | INTEGER |
| name | имя покупателя | VARCHAR(255) | ||
| электронная почта покупателя | VARCHAR(255) | |||
| phone | контактный номер телефона покупателя | VARCHAR(255) | ||
| state | идентификатор статуса покупателя | INTEGER | ||
| sysuser | идентификатор системного пользователя | INTEGER | ||
| Статус покупателя | customer_states | id | уникальный идентификатор статуса покупателя | INTEGER |
| name | название статуса покупателя | VARCHAR(255) | ||
| Пользователь | users | id | уникальный идентификатор пользователя | INTEGER |
| login | логин пользователя | VARCHAR(255) | ||
| password | пароль пользователя | VARCHAR(255) | ||
| role | роль пользователя | VARCHAR(255) | ||
| JWT-токен | jwts | id | уникальный идентификатор JWT | INTEGER |
| published | дата и время публикации JWT | TIMESTAMP | ||
| token | токен JWT | TEXT | ||
| sysuser | идентификатор системного пользователя | INTEGER |
Схема физической модели данных выглядит так:

Спроектировав схему модели данных в сервисе drawsql.app, я получила DDL-скрипт на создание таблиц для PostgreSQL:
CREATE TABLE "delivery"(
"id" INTEGER NOT NULL,
"date" DATE NOT NULL,
"address" TEXT NOT NULL,
"price" DOUBLE PRECISION NOT NULL
);
ALTER TABLE
"delivery" ADD PRIMARY KEY("id");
CREATE TABLE "order_product"(
"id" INTEGER NOT NULL,
"order" INTEGER NOT NULL,
"product" INTEGER NOT NULL,
"quantity" INTEGER NOT NULL
);
ALTER TABLE
"order_product" ADD PRIMARY KEY("id");
CREATE TABLE "product"(
"id" INTEGER NOT NULL,
"name" VARCHAR(255) NOT NULL,
"provider" INTEGER NOT NULL,
"price" DOUBLE PRECISION NOT NULL,
"quantity" INTEGER NOT NULL
);
ALTER TABLE
"product" ADD PRIMARY KEY("id");
CREATE TABLE "customer_states"(
"id" INTEGER NOT NULL,
"name" VARCHAR(255) NOT NULL
);
ALTER TABLE
"customer_states" ADD PRIMARY KEY("id");
CREATE TABLE "jwts"(
"id" INTEGER NOT NULL,
"published" TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
"token" TEXT NOT NULL,
"sysuser" INTEGER NOT NULL
);
ALTER TABLE
"jwts" ADD PRIMARY KEY("id");
CREATE TABLE "users"(
"id" INTEGER NOT NULL,
"login" VARCHAR(255) NOT NULL,
"password" VARCHAR(255) NOT NULL,
"role" VARCHAR(255) CHECK
("role" IN('')) NOT NULL
);
ALTER TABLE
"users" ADD PRIMARY KEY("id");
CREATE TABLE "order_states"(
"id" INTEGER NOT NULL,
"name" VARCHAR(255) NOT NULL
);
ALTER TABLE
"order_states" ADD PRIMARY KEY("id");
CREATE TABLE "provider"(
"id" INTEGER NOT NULL,
"name" VARCHAR(255) NOT NULL,
"phone" VARCHAR(255) NOT NULL,
"email" VARCHAR(255) NOT NULL,
"address" VARCHAR(255) NOT NULL
);
ALTER TABLE
"provider" ADD PRIMARY KEY("id");
CREATE TABLE "orders"(
"id" INTEGER NOT NULL,
"customer" INTEGER NOT NULL,
"state" INTEGER NOT NULL,
"delivery" INTEGER NOT NULL,
"sum" DOUBLE PRECISION NOT NULL,
"date" DATE NOT NULL
);
ALTER TABLE
"orders" ADD PRIMARY KEY("id");
CREATE TABLE "customer"(
"id" INTEGER NOT NULL,
"name" VARCHAR(255) NOT NULL,
"email" VARCHAR(255) NOT NULL,
"phone" VARCHAR(255) NOT NULL,
"state" INTEGER NOT NULL,
"sysuser" INTEGER NOT NULL
);
ALTER TABLE
"customer" ADD PRIMARY KEY("id");
ALTER TABLE
"product" ADD CONSTRAINT "product_provider_foreign" FOREIGN KEY("provider") REFERENCES "provider"("id");
ALTER TABLE
"order_product" ADD CONSTRAINT "order_product_order_foreign" FOREIGN KEY("order") REFERENCES "orders"("id");
ALTER TABLE
"customer" ADD CONSTRAINT "customer_sysuser_foreign" FOREIGN KEY("sysuser") REFERENCES "users"("id");
ALTER TABLE
"order_product" ADD CONSTRAINT "order_product_product_foreign" FOREIGN KEY("product") REFERENCES "product"("id");
ALTER TABLE
"customer" ADD CONSTRAINT "customer_state_foreign" FOREIGN KEY("state") REFERENCES "customer_states"("id");
ALTER TABLE
"orders" ADD CONSTRAINT "orders_delivery_foreign" FOREIGN KEY("delivery") REFERENCES "delivery"("id");
ALTER TABLE
"orders" ADD CONSTRAINT "orders_state_foreign" FOREIGN KEY("state") REFERENCES "order_states"("id");
ALTER TABLE
"orders" ADD CONSTRAINT "orders_customer_foreign" FOREIGN KEY("customer") REFERENCES "customer"("id");
ALTER TABLE
"jwts" ADD CONSTRAINT "jwts_sysuser_foreign" FOREIGN KEY("sysuser") REFERENCES "users"("id");
Создав с помощью этого скрипта таблицы в облачном экземпляре PostreSQL, развернутом в serverless-платформе Neon, я наполнила таблицы фейковыми данными с помощью ранее написанного Python-скрипта для генерации INSERT-запросов фейковых данных, рассмотренного здесь.
Основы архитектуры и интеграции информационных систем
Код курса
OAIS
Ближайшая дата курса
17 ноября, 2025
Продолжительность
25 ак.часов
Стоимость обучения
56 000 руб.
Разработка спецификации OpenAPI
Поскольку речь идет о разработке REST-приложения, целесообразно выполнить проектирование маршрутов и конечных точек в виде спецификации OpenAPI. Для этого сопоставим сущности с маршрутами. С учетом ограниченного объема проектируемого MVP, не все ранее выделенные сущности будут материализованы в виде представлений ресурсов, доступных по маршрутам. Но, с учетом необходимости выполнения некоторых системных вариантов использования, в частности, аутентификации и регистрации пользователя в системе, будут добавлены некоторые маршруты, не связанные с сущностями в БД напрямую, например, /login, /registration.
| Сущность | Таблица БД | Маршрут |
| Товар | product
|
/product |
| Поставщик | provider | /provider |
| Заказ | orders | /order |
| Пользователь
JWT-токен |
users
jwts |
/login |
| Пользователь | users | /registration |
Теперь сопоставим системные варианты использования с конечными точками, т.е. HTTP-методами, которые будут обращаться к маршрутам.
| Актор | Use Case | Маршрут | HTTP-запрос | Аутентификация |
| Пользователь (Покупатель, Менеджер) | UC 0 Войти в систему | /login | GET | нет |
| Пользователь (Покупатель, Менеджер) | UC 0.1 Аутентификация | /login | POST | нет |
| Пользователь (Покупатель, Менеджер) | UC 0.2 Зарегистрироваться | /registration | GET, POST | нет |
| Пользователь (Покупатель, Менеджер) | UC 1.1 Посмотреть список товаров | /product | GET | нет |
| Менеджер | UC 2.1.1 Добавить товар | /product | POST | да |
| Менеджер | UC 2.1.2 Посмотреть товар | /product /{id} | GET | да |
| Менеджер | UC 2.1.3 Изменить товар | /product /{id} | PUT | да |
| Менеджер | UC 2.1.4 Удалить товар | /product /{id} | DELETE | да |
| Пользователь (Покупатель, Менеджер) | UC 1.2 Посмотреть список поставщиков | /provider | GET | нет |
| Менеджер | UC 2.2.1 Добавить поставщика | /provider | POST | да |
| Менеджер | UC 2.2.2 Посмотреть поставщика | /provider/{id} | GET | да |
| Менеджер | UC 2.2.3 Изменить поставщика | /provider/{id} | PUT | да |
| Менеджер | UC 2.2.4 Удалить поставщика | /provider/{id} | DELETE | да |
| Менеджер | UC 3.1 Посмотреть список заказов | /order | GET | да |
| Менеджер | UC 3.2.1 Посмотреть заказ | /order/{id} | GET | да |
| Менеджер | UC 3.2.2 Изменить состояние заказа | /order/{id} | PUT | да |
Разумеется, при проектировании REST API необходимо определить тело для каждого POST и PUT-запроса, а также статусы HTTP-ответов и их смысл. В целях экономии места сделаем это сразу в спецификации OpenAPI:
openapi: 3.0.0
servers:
# Added by API Auto Mocking Plugin
- description: SwaggerHub API Auto Mocking
url: https://virtserver.swaggerhub.com/VICHIGOVAANNA/Internet-shop/1.1
info:
description: 'Типичный интернет-магазин - демо-кейс Анны Вичуговой (упрощенная версия для реализации MVP на Python, с JWT-аутентификацией в куки)'
version: '1.1'
title: API интернет-магазина (упрощенное демо)
contact:
email: anna@mail.com
tags:
- name: user
description: Пользователь (все категории пользователей)
- name: manager
description: Менеджер
- name: customer
description: Покупатель
paths:
/registration:
get:
tags:
- user
description: Просмотр страницы регистрации пользователя в системе
summary: Просмотр страницы регистрации пользователя в системе
responses:
'200':
description: Успешно отображена страница регистрации
'500':
description: Внутренняя ошибка сервера
post:
tags:
- user
summary: Регистрация пользователя в системе
description: Регистрация нового пользователя
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UserData'
responses:
'200':
description: Успешная регистрация пользователя
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'401':
description: Ошибка аутентификации, неверные учетные данные
'500':
description: Внутренняя ошибка сервера
/login:
get:
tags:
- user
description: Просмотр страницы ввода логина и пароля (входа в систему)
summary: Просмотр страницы ввода логина и пароля (входа в систему)
responses:
'200':
description: Успешно отображена страница аутентификации
'500':
description: Внутренняя ошибка сервера
post:
tags:
- user
summary: Вход пользователя в систему
description: Аутентификация пользователя для генерации JWT-токена и его записи в куки
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UserData'
responses:
'200':
description: Успешная аутентификация зарегистрированного пользователя, формирование JWT-токена и его запись в куки
headers:
Set-Cookie:
schema:
type: string
example: eyJ0eXAwcvvcb1QiLCJhbGciOsdfsUzI1NiJ9.eyJpZCI6IjEzMzciLCJ1c2VybmFtZSI6ImJpem9uZSIswwwfcI6MTU5NDIwOTYwMCwicm9sZSI6InVzZXIifQ.ZvkYYnyM92xvxcvNW9_hSis7_x3_9rymsDcvcbvuOcc1I
'401':
description: Ошибка аутентификации, неверные учетные данные
'500':
description: Внутренняя ошибка сервера
/product:
get:
tags:
- manager
- customer
- user
summary: Посмотреть каталог товаров
operationId: viewProductCatalog
description: Параметры фильтрации товаров в каталоге для поиска
parameters:
- in: query
name: name
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/ProductData'
'400':
description: не верные параметры фильтрации
post:
tags:
- manager
summary: 'Добавить товар'
operationId: addProduct
security:
- cookieAuth: []
description: Добавить новый товар в каталог
responses:
'201':
description: товар добавлен
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
'400':
description: некорректный ввод
'409':
description: такой товар уже есть
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ProductData'
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: phone
description: телефон поставщика для поиска
required: false
schema:
type: string
- in: query
name: email
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/ProviderData'
'400':
description: не верные параметры фильтрации
post:
tags:
- manager
summary: Добавить поставщика
operationId: addProvider
security:
- cookieAuth: []
description: Добавление нового поставщика в каталог
responses:
'201':
description: поставщик добавлен
content:
application/json:
schema:
$ref: '#/components/schemas/Provider'
'400':
description: некорректный ввод
'409':
description: такой поставщик уже есть
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ProviderData'
description: Новый поставщик для добавления в каталог
/product/{id}:
get:
tags:
- manager
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:
- cookieAuth: []
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:
- cookieAuth: []
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
summary: Посмотреть поставщика
operationId: viewProvider
security:
- cookieAuth: []
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:
- cookieAuth: []
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:
- cookieAuth: []
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
summary: Посмотреть заказы
operationId: viewOrders
security:
- cookieAuth: []
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}:
put:
tags:
- manager
summary: Изменить состояние заказа
security:
- cookieAuth: []
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:
$ref: '#/components/schemas/OrderState'
components:
schemas:
Product:
required:
- id
- product_data
properties:
id:
type: integer
example: 1
product_data:
$ref: '#/components/schemas/ProductData'
ProductData:
type: object
required:
- id
- name
- provider
- price
- quantity
properties:
id:
type: integer
example: 1
name:
type: string
example: 'яблоки'
provider:
$ref: '#/components/schemas/Provider'
price:
type: number
minimum: 0.001
maximum: 100500
example: 145.00
quantity:
type: integer
minimum: 1
maximum: 100500
example: 10
Provider:
required:
- id
- provider_data
properties:
id:
type: integer
example: 1
provider_data:
$ref: '#/components/schemas/ProviderData'
ProviderData:
required:
- name
- phone
- email
- address
properties:
name:
type: string
example: ООО Ромашка
phone:
type: string
example: 7-495-123-45-67
email:
type: string
example: example@example.com
address:
type: string
example: г. Москва, ул. Ленина, 123
Order:
required:
- id
- customer
- state
- delivery
- sum
- date
properties:
id:
type: integer
description: ИД заказа
example: 1
customer:
type: integer
description: ИД клиента
example: 1
state:
type: integer
enum:
- 2
- 3
- 5
description: состояние заказа, 2 в обработке, 3 собран, 5 отменен магазином
example: 2
delivery:
type: string
description: адрес доставки заказа
example: Москва, ул. Тверская, 48, кв. 35
sum:
type: number
description: сумма заказа
example: 1450.00
date:
type: string
description: дата создания заказа
format: date
example: 2023-09-30
OrderState:
required:
- state
properties:
state:
type: integer
enum:
- 2
- 3
- 5
description: 2 в обработке, 3 собран, 5 отменен магазином
example: 2
User:
required:
- id
- user_data
properties:
id:
type: integer
example: 1
user_data:
$ref: '#/components/schemas/UserData'
UserData:
type: object
properties:
username:
type: string
description: Логин пользователя
example: anna_vi
password:
type: string
format: password
description: Пароль пользователя
role:
type: string
enum:
- customer
- manager
description: роль пользователя в системе, customer покупатель, manager сотрудник магазина
securitySchemes:
cookieAuth:
type: apiKey
in: cookie
name: token # название куки, в который записывается сгенерированный JWT-токен
Редактор Swager UI визуализирует эту спецификацию и позволяет протестировать ее.

Эта спецификация доступна для просмотра по ссылке. В следующей статье я расскажу, почему аутентификация с JWT-токеном была реализована с помощью файлов cookie, а также покажу UML-диаграмму последовательности для вариантов использования, требующих наличия этих самых куки.
Основы бизнес-анализа: вход в профессию для начинающих
Код курса
INTRO
Ближайшая дата курса
12 января, 2026
Продолжительность
24 ак.часов
Стоимость обучения
54 000 руб.
Освоить все использованные в этом материале и другие техники работы аналитика вам помогут мои курсы в Школе прикладного бизнес-анализа на базе нашего лицензированного учебного центра обучения и повышения квалификации системных и бизнес-аналитиков в Москве:
- Основы бизнес-анализа: вход в профессию для начинающих
- Разработка ТЗ на информационную систему
- UML для бизнес-аналитика
- Основы архитектуры и интеграции информационных систем


