...

Проектирование REST API на примере интернет-магазина

Проектирование REST API для аналитика пример, разработка модели данных практический пример, как аналитику спроектировать REST API, архитектура информационных систем примеры курсы обучение, системный анализ на пальцах простой пример для начинающих, техники бизнес-анализа, Карта влияния (Impact Map) пример, обучение аналитиков, техники бизнес-анализа для начинающих, UML Use Case примеры, обучение начинающих аналитиков, курсы бизнес-анализа, курсы системного анализа, Школа прикладного бизнес-анализа Учебный центр Коммерсант

Чтобы показать, как устроена 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
Ближайшая дата курса
24 февраля, 2025
Продолжительность
16 ак.часов
Стоимость обучения
36 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 по областям действия пользовательских историй.

Управление товарами визуализирует следующая диаграмма.

Управление товарами в интернет-магазине, UML-диаграмма Use Case, UML для аналитика пример
Управление товарами в интернет-магазине

Эта диаграмма создана с помощью следующего PlantUML-скрипта:

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

Управление поставщиками визуализирует следующая диаграмма.

Управление поставщиками в интернет-магазине, UML-диаграмма Use Case, UML для аналитика пример
Управление поставщиками в интернет-магазине

Эта диаграмма создана с помощью следующего PlantUML-скрипта:

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

Наконец, управление заказами визуализирует следующая диаграмма.

Управление заказами в интернет-магазине, UML-диаграмма Use Case, UML для аналитика пример
Управление заказами в интернет-магазине

Эта диаграмма создана с помощью следующего PlantUML-скрипта:

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

DDD, ООП и UML для аналитика

Код курса
BUML
Ближайшая дата курса
31 марта, 2025
Продолжительность
16 ак.часов
Стоимость обучения
36 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)
email электронная почта поставщика 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)
email электронная почта покупателя 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

Схема физической модели данных выглядит так:

Физическая модель данных интернет-магазина для PostgreSQL, проектирование модели данных PostgreSQL
Физическая модель данных интернет-магазина для PostgreSQL

Спроектировав схему модели данных в сервисе 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
Ближайшая дата курса
20 января, 2025
Продолжительность
16 ак.часов
Стоимость обучения
36 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 визуализирует эту спецификацию и позволяет протестировать ее.

Спецификация OpenAPI для интернет-магазина, пример OpenAPI спецификации, спецификация REST API
Спецификация OpenAPI для интернет-магазина

Эта спецификация доступна для просмотра по ссылке. В следующей статье я расскажу, почему аутентификация с JWT-токеном была реализована с помощью файлов cookie, а также покажу UML-диаграмму последовательности для вариантов использования, требующих наличия этих самых куки.

Основы бизнес-анализа: вход в профессию для начинающих

Код курса
INTRO
Ближайшая дата курса
13 января, 2025
Продолжительность
24 ак.часов
Стоимость обучения
54 000 руб.

Освоить все использованные в этом материале и другие техники работы аналитика вам помогут мои курсы в Школе прикладного бизнес-анализа на базе нашего лицензированного учебного центра обучения и повышения квалификации системных и бизнес-аналитиков в Москве:

 

Я даю свое согласие на обработку персональных данных и соглашаюсь с политикой конфиденциальности.

Добавить комментарий