При том, что проектирование и выбор решения относится к области ИТ-архитектора, иногда аналитику приходится решать подобные задачи, особенно в задачах интеграции информационных систем. Рассмотрим на примере интернет-магазина, на какие самые важные вопросы должен ответить аналитик при разработке требований и/или первоначальном проектировании веб-API.
Функциональные требования
Возьмем в качестве примера типичный интернет-магазин, который представляет собой веб-приложение. Как я описывала здесь, клиент (слой представления, фронтенд) в виде браузера или мобильного приложения, обращается к серверной части (бэкенду) не напрямую, а через веб-сервер (Apache HTTP, Nginx, Google Web Server, lighttpd и пр.), который принимает HTTP-запросы от клиентов и выдает им HTTP-ответы, а также может выполнять функции маршрутизации и балансировки запросов. Сервер веб-приложения уже обращается к базе данных, направляя соответствующий SQL-запрос по предварительно настроенному подключению с помощью JDBC или ODBC-драйверов.
Пользователей интернет магазина можно разделить на 2 категории, т.е. роли: покупатели и сотрудники. Все пользователи могут просматривать каталог всех товаров, искать товары определенных характеристик с применением различных фильтров, а также просмотреть детали конкретного товара. Покупатель может добавить товар в корзину и купить его через шлюз онлайн-оплаты (внешняя система по отношению к интернет-магазину). Причем для покупки покупателю совсем не обязательно выполнять вход в систему, т.е. проходить процедуру аутентификации. Однако, чтобы снизить стоимость заказа на сумму своей персональной скидки, которая выдается покупателю в зависимости от его истории покупок, это придется сделать. Сотрудник интернет-магазина может выполнять различные манипуляции с товарами: добавлять новые и изменять/удалять существующие. Также сотрудник может формировать различные отчеты, например, по продажам отдельных товаров или товарных категорий, заказам и покупателям.
Чтобы визуализировать функциональные требования к системе в виде набора вариантов использования, которые она предоставляет своим пользователям, составим UML-диаграмму Use Case. Но перед этим сделаем таблицу с этими вариантами использования (реестр), чтобы видеть их полный перечень.
Актор | Целевой юзкейс | Системные юзкейсы (расширения и включения) | ||
Пользователь (Покупатель, Сотрудник) | UC 1. Войти в систему | UC 1.1 Регистрация (расширение) | ||
UC 1.2 Аутентификация (расширение) | ||||
UC 2. Найти товар | UC2.1 Посмотреть каталог (включение) | |||
UC 2.2 Посмотреть товар (расширение) | ||||
Сотрудник | UC 3. Сформировать отчет | UC 1.2 Аутентификация (включение) | ||
UC 4. Добавить новый товар | UC 1.2 Аутентификация (включение) | |||
UC 4.1 Изменить товар (расширение) | ||||
UC 4.2 Удалить товар (расширение) | ||||
Покупатель, Шлюз онлайн-оплаты | UC 5. Купить товар | UC 5.1 Сделать заказ (включение) | UC 5.1 Добавить товар в корзину (включение) | UC 2.2 Посмотреть товар (включение) |
UC 5.1.1 Удалить товар из корзины (расширение) | ||||
UC 5.1.2 Изменить количество товара в корзине (расширение) | ||||
UC 5.2 Применить скидку (расширение) |
Теперь визуализируем этот реестр вариантов использования в виде UML-диаграммы Use Case в веб-движке PlantUML (https://www.plantuml.com/).
Чтобы онлайн-сервер PlantUML сформировал такую UML-диаграмму, я написала следующее текстовое определение для этого веб-движка:
@startuml skinparam packageStyle rectangle actor Пользователь actor Сотрудник actor Покупатель actor Шлюз_онлайн_оплаты Пользователь <|- :Сотрудник: Пользователь <|- :Покупатель: rectangle Интернет_магазин { Пользователь --> (Войти в систему) (Регистрация) .> (Войти в систему) : extend (Аутентификация) .> (Войти в систему) : extend (Применить скидку) .-> (Аутентификация) : include Покупатель --> (Купить товар) (Применить скидку) ...> (Купить товар) : extend (Купить товар) -- Шлюз_онлайн_оплаты (Добавить новый товар) .-> (Аутентификация) : include Пользователь --> (Найти товар) (Посмотреть товар) .> (Найти товар) : extend Сотрудник --> (Добавить новый товар) Сотрудник -> (Сформировать отчет) (Сформировать отчет) ..-> (Аутентификация) : include (Изменить товар) ..> (Добавить новый товар) : extend (Удалить товар) ..> (Добавить новый товар) : extend (Найти товар) .-> (Просмотреть каталог) : include (Купить товар) .-> (Сделать заказ) : include (Сделать заказ) ..> (Добавить товар в корзину) : include (Добавить товар в корзину) ..> (Посмотреть товар) : include (Удалить товар из корзины) ..> (Добавить товар в корзину) : extend (Изменить количество товара в корзине) ..> (Добавить товар в корзину) : extend } @enduml
DDD, ООП и UML для аналитика
Код курса
BUML
Ближайшая дата курса
9 декабря, 2024
Продолжительность
16 ак.часов
Стоимость обучения
36 000 руб.
Разумеется, такой диаграммы недостаточно для полного описания функциональных требований к веб-API, однако, она дает обзор возможностей и границ проектируемой системы. Эта диаграмма позволяет определить набор базовых сущностей предметной области (Сотрудник, Покупатель, Товар, Заказ, Платеж), которые лягут в основу модели данных, что мы рассмотрим далее.
Моделирование данных
Для упрощения нашего примера рассмотрим участок модели данных, касающийся данных о покупателях, заказах, товарах и платежах.
Согласно этой модели данных, при добавлении нового продукта, в систему будет отправляться HTTP-запрос со следующей полезной нагрузкой, представленной в человеко-читаемом формате JSON:
{ "name": "платье", "price": 3520, "provider": "Zolla" }
Однако, кроме полезной нагрузки в теле HTTP-запроса POST, используемого для UC 4. Добавить новый товар, также также будут заголовки этого сообщения, с типом контента, ожидаемым клиентом от сервера, клиентским ПО для с сервером (в нашем случае это браузер или мобильное приложение), cookie клиента, также учетные данные аутентификации. Поскольку, согласно ранее определенным функциональным требованиям, добавлять новые товары может только сотрудник, в HTTP-заголовок этого POST-запроса, необходимы учетные данные, которые аутентифицируют пользователя, вызывающего API-метод. Подробно про виды аутентификации веб-API я недавно рассказывала здесь.
Таким образом, передача учетных данных аутентификации в HTTP-запросе решает задачу реализации stateful-системы в рамках stateless-технологии. В частности, изначально REST API позиционируется как stateless, т.е. сервер не сохраняет состояние клиента. Однако, очень часто, даже в нашем примере, ответ сервера фактически зависит от клиента. Но реализация stateful-систем на порядок сложнее, чем систем без сохранения состояния клиента, а также они намного хуже масштабируются. Поэтому добавление метаданных в заголовок HTTP-запроса, таких как учетные данные или cookie, можно рассматривать как попытку воплощения stateful-системы в stateless-API. Разумеется, если конфиденциальные данные, передаваемые в теле или заголовке HTTP-запроса, следует защитить от возможных утечек. Например, вместо HTTP использовать защищенное расширение этого протокола — HTTPS, в котором данные передаются с TLS-криптографией, обеспечивая защиту от атак. А вторая версия HTTP-протокола, HTTP/2, на которой работает gRPC API, хотя и определяет шифрование как необязательное, в большинстве браузеров поддерживается только поверх TLS. Если конфиденциальные данные содержатся не только в заголовке, но и в теле HTTP-запроса, их также можно сперва зашифровать на стороне клиента перед отправкой на сервер, где они будут приняты, расшифрованы и обработаны соответствующим образом.
Определившись с полезной нагрузкой и метаданными в заголовках HTTP-запросов и ответов, при проектировании веб-API аналитик решает, как упаковать эти данные для передачи, т.е. какой формат выбрать. На этот выбор может влиять технология реализации веб-API.
REST | SOAP | GraphQL | gRPC |
JSON, XML, TXT, HTML | XML | JSON | Protobuf |
Все эти форматы данных разную скорость преобразования данных в битовую последовательность и обратно, а также размер выходного сообщения. Помимо этих критериев нужно учитывать также удобство использования формата и возможность эволюции схемы. Подробнее про JSON, XML, YAML и Protobuf с примерами сообщений, я писала в отдельной статье. Сведения о формате данных, отправляемых от клиента на сервер и наоборот, записываются в заголовки HTTP-запросов и ответов (Accept и Content-type соответственно).
Помимо разработки модели данных с определением формата и схемы сообщений, передаваемых от клиента серверу и наоборот, следует понять сложность бизнес-логики обработки данных, упакованных в эту модель. Если все функции проектируемой системы сводятся к выполнению примитивных CRUD-операций с данными, например, добавить/посмотреть/изменить/удалить товар, их можно относительно просто реализовать с помощью REST-фреймворков, например, FastAPI, о чем я рассказывала здесь.
Но UC 3. Сформировать отчет в рассматриваемом примере интернет-магазина представляет собой не просто HTTP-запрос к ресурсу, а вызов более сложной процедуры на удаленном сервере. Например, чтобы получить отчет о том, какие покупатели сделали платежи в этом месяце и за какие товары, в REST API придется делать несколько GET-запросов к разным ресурсам через несколько конечных точек (/customer, /order, /product, /payment). Большое количество запросов, на каждый из которых открывается новое соединение, снижает скорость работы системы. Особенно это заметно, если данные для формирования отчета хранятся в разных представлениях, связанных с набором таблицам одной или даже нескольких БД, являясь результатом выполнения сложного SQL-запроса. В этом случае имеет смысл посмотреть в сторону GraphQL или SOAP. При проектировании веб-API, реализующего технологию удаленного вызова процедур (GraphQL, SOAP или gRPC) важно называть вызываемые методы понятными именами. Это означает, что функции веб-API должны иметь семантически понятное наименование, например, GetCustomerOrderMonthStatistics(). Здесь аналитик уже сильно заходит на территорию разработчика, поэтому для принятия таких решений необходимо иметь общий для всей команды документ, похожий на модельное соглашение, с правилами и шаблонами для создания различных артефактов.
Разработка ТЗ на информационную систему по ГОСТ и SRS
Код курса
TTIS
Ближайшая дата курса
2 декабря, 2024
Продолжительность
16 ак.часов
Стоимость обучения
36 000 руб.
Алгоритм проектирования веб-API: 7 главных шагов
После полного определения всех функциональных требований и содержания передаваемых данных, необходимо определиться с нефункциональными требованиями, т.е. условиями и ограничениями, в которых система должна реализовывать свои функции. Особенно тщательно следует проработать вопросы производительности системы и допустимой задержки обработки данных. В частности, какова частота запуска того или иного Use Case, сколько времени клиент может ожидать ответа от сервера, допускается ли в этот период отправка других запросов (асинхронный характер взаимодействия) или нет (синхронное общение). Ответы на эти вопросы помогут выбрать наиболее подходящую технологию.
Таким образом, алгоритм проектирования веб-API можно представить в виде следующих шагов:
- Уточнить функциональные требования – какие возможности должна предоставлять система для каких акторов, какие она будет выполнять функции с какими данными;
- Определить нефункциональные требования, уделив особенное внимание вопросам производительности и допустимой задержки отклика на вызов функций;
- Выбрать подходящую технологию с учетом предыдущих пунктов;
- Решить вопрос насчет сохранения состояний клиента на сервера (система stateless или stateful);
- Определиться с необходимостью аутентификации и способом ее реализации;
- Называть вещи своими именами. В частности, при выборе архитектурного стиля REST для своего API, конечные точки для доступа к ресурсам рекомендуется называть семантически понятными именами. Например, /products подходит для обращения к данным о продуктах (товарах), а /orders – для данных о заказах. Аналогичное правило применимо для именования функций, вызываемых на удаленном сервере при использовании технологий SOAP, GraphQL или gRPC. Например, название GetCustomerOrderMonthStatistics() гораздо понятнее, чем getstat().
- Передавайте только нужные данные в подходящем формате. Кроме того, что аналитик должен определиться с форматом и содержанием передаваемых между клиентом и сервером сообщений, надо также подумать об их размере. Чтобы ускорить передачу данных по сети и их обработку, следует максимально ограничить объем передаваемых данных от клиента к серверу и обратно. Например, не сообщать клиенту все 48 характеристик товара, собираемых из разных источников, без специального запроса на просмотр дополнительных сведений, которые в действительности возникают довольно редко.
Пример использования этих принципов на практике продемонстрирован в моей новой статье про проектирование и реализацию собственного REST-приложения на Python с фреймворком Flask и СУБД SQLLite. А здесь я рассказываю про стандарты и практики архитектурного проектирования ИС.
Разумеется, в этой небольшой статье раскрыты не все нюансы практической работы проектирования веб-API. В большинстве случаев дизайн ПО – это область ответственности ИТ-архитектора, а не аналитика. Но аналитику важно и нужно понимать основные аспекты этой деятельности, чтобы успешно решать задачи разработки требований к информационным системам и для работы в проектах интеграции.
Основы архитектуры и интеграции информационных систем
Код курса
OAIS
Ближайшая дата курса
20 января, 2025
Продолжительность
16 ак.часов
Стоимость обучения
36 000 руб.
Подробнее про все эти и другие аспекты архитектуры и интеграции информационных систем, я рассказываю на своих курсах Школы прикладного бизнес-анализа в нашем лицензированном учебном центре обучения и повышения квалификации системных и бизнес-аналитиков в Москве:
- Основы архитектуры и интеграции информационных систем
- UML для бизнес-аналитика
- Разработка ТЗ на информационную систему по ГОСТ и SRS