А.6 API и интеграции глазами аналитика
Зачем это аналитику
Системы почти никогда не живут одни: магазин обменивается данными со складом, платёжным шлюзом, службой доставки, бухгалтерией. Большая часть работы системного аналитика — описать, кто кому что передаёт, когда и что происходит при сбое. Этот модуль даёт словарь и базовые способы интеграции, чтобы выбирать между ними осознанно.
Готовность к модулю
Модуль опирается на темы ниже. Если какая-то из них незнакома или её вопросы для самопроверки даются с трудом, начните с неё.
Куда ведёт
Тема подробнее раскрывается в модулях:
- А.7 UML и BPMN
- А.9 Системные требования
- Б.3 Контракты API
- Б.5 Асинхронный обмен
- 3.4 Коммуникация и брокеры
- 8.4 Пакетные интеграции
Что понять
- Что такое интеграция и какие вопросы она ставит: кто инициатор, какие данные, как часто, что при ошибке.
- REST API на базовом уровне: ресурсы, методы, коды ответа, JSON. Чтение документации Swagger/OpenAPI.
- Синхронный вызов и асинхронный обмен: когда ответ нужен сразу, а когда можно подождать.
- Очередь сообщений на уровне идеи: отправитель, брокер, получатель; почему сообщение не теряется, если получатель недоступен.
- Вебхуки: когда система сама сообщает о событии.
- Файловый обмен и пакетные выгрузки: по расписанию, через каталог или SFTP.
- Прямой доступ к чужой базе данных — почему это плохая идея.
- Ошибки и повторы: таймаут, повторная отправка, дубли; идемпотентность на пальцах.
- Что писать в спецификации интеграции: участники, сценарии, формат, ошибки, нефункциональные требования.
Урок
Что такое интеграция
Интеграция — это договорённость двух систем о том, как одна передаёт другой данные или просит что-то сделать. Внутри одной программы код просто вызывает свою же функцию. Между системами всё иначе: они написаны разными командами, работают на разных серверах, падают и обновляются независимо, а связывает их сеть, которая может потерять запрос или ответ.
Представьте интернет-магазин. Покупатель оформил заказ — и в работу включаются склад (резерв и сборка), платёжный шлюз (сервис, который принимает оплату картой и общается с банками), служба доставки, бухгалтерия и сервис рассылок. Каждая стрелка между этими системами — отдельная интеграция. Для каждой аналитик отвечает на четыре базовых вопроса:
- Кто инициатор? Кто начинает обмен: магазин спрашивает склад или склад сам сообщает магазину.
- Какие данные? Состав полей, формат, объём одного сообщения.
- Как часто и насколько срочно? В момент действия пользователя, раз в минуту, раз в сутки.
- Что при ошибке? Получатель недоступен, ответ не пришёл, пришли кривые данные — кто это заметит и что будет делать.
Четвёртый вопрос чаще всего пропускают, а в нём прячутся потерянные заказы и двойные списания.
REST API на базовом уровне
API (Application Programming Interface, программный интерфейс) — это «окно выдачи» системы для других программ: набор операций, которые можно вызвать, и правила, в каком виде передавать запрос и получать ответ. Человек работает с системой через экраны, программа — через API.
Самый распространённый стиль веб-API — REST. Не вдаваясь в теорию, на практике он означает следующее.
Ресурсы. Всё, с чем работает API, — это ресурсы: заказы, товары, покупатели. У каждого ресурса есть адрес (URL): /orders — все заказы, /orders/1045 — заказ с номером 1045.
Методы. Что сделать с ресурсом, говорит метод HTTP-запроса (о самом HTTP — в модуле А.2):
| Метод | Смысл | Пример |
|---|---|---|
| GET | Получить данные, ничего не меняя | GET /orders/1045 — прочитать заказ |
| POST | Создать новый ресурс или запустить действие | POST /orders — создать заказ |
| PUT | Заменить ресурс целиком | PUT /orders/1045 — перезаписать заказ |
| PATCH | Изменить часть полей | PATCH /orders/1045 — поменять адрес доставки |
| DELETE | Удалить | DELETE /orders/1045 — отменить или удалить заказ |
Коды ответа. Каждый ответ начинается с трёхзначного кода. Первая цифра говорит о классе результата: 2xx — успех, 4xx — ошибка на стороне того, кто спрашивает (неверные данные, нет прав, ресурс не найден), 5xx — ошибка на стороне того, кто отвечает (сервер упал, внутренний сбой). Самые частые: 200 (успех), 201 (создано), 400 (некорректный запрос), 404 (не найдено), 409 (конфликт с текущим состоянием, например попытка отменить уже отправленный заказ), 500 (внутренняя ошибка), 503 (сервис временно недоступен).
Разделение 4xx и 5xx важно аналитику: при 4xx повторять тот же запрос, как правило, бессмысленно — надо исправлять данные (есть исключения, например 429 «слишком много запросов»: там повтор после паузы уместен); при 5xx повтор через какое-то время может помочь.
JSON. Тело запроса и ответа обычно передаётся в формате JSON (модуль А.3). Запрос на создание заказа мог бы выглядеть так:
POST /orders HTTP/1.1
Content-Type: application/json
{
"customer_id": 311,
"items": [
{ "product_id": 58, "quantity": 2 }
],
"delivery_address": "ул. Садовая, 10, кв. 4"
}
В ответ сервер вернёт код 201 и JSON с номером созданного заказа, статусом и суммой.
Как читать документацию Swagger/OpenAPI
OpenAPI — стандартный формат описания REST API: какие есть адреса, какие методы на них работают, что передать и что придёт в ответ. Swagger — набор инструментов вокруг этого формата, самый известный — Swagger UI, веб-страница, где описание API показано в удобном виде.
В описании метода ищите: путь и метод (POST /orders); параметры в адресе (/orders/{id}) или после знака вопроса (?status=new); схему тела запроса с типами и обязательностью; ответы отдельно для каждого кода; способ, которым клиент доказывает, кто он (ключ API или токен — выданная заранее секретная строка-пропуск, которую передают с каждым запросом).
Хорошее описание содержит примеры запросов и ответов. Если их нет, а ошибки описаны только кодом 200 — это повод для вопросов разработчику ещё до начала работы.
Синхронный вызов и асинхронный обмен
Синхронный вызов похож на телефонный звонок: вы спросили и ждёте ответа, не кладя трубку. Магазин отправил запрос в платёжный шлюз и ждёт «оплачено» или «отказ», а покупатель тем временем смотрит на крутящееся колесо.
Асинхронный обмен похож на письмо: отправили и занялись другими делами, ответ (если нужен) придёт позже. Магазин сообщил «заказ оплачен», а склад обработает это, когда сможет.
Как выбирать:
- Синхронно — когда результат нужен прямо сейчас, чтобы продолжить: проверить остаток перед оформлением, узнать результат оплаты, показать пользователю цену доставки.
- Асинхронно — когда отправителю достаточно знать, что сообщение принято: передать заказ на сборку, выгрузить продажу в бухгалтерию, отправить письмо.
Цена синхронности — связанность. Если склад лежит, а магазин ждёт его ответа при каждом оформлении, магазин тоже перестаёт продавать. Асинхронный обмен развязывает системы во времени: каждая работает в своём темпе. Цена асинхронности — сложность: результат приходит позже, его надо где-то ждать, а пользователю — показывать промежуточное состояние («заказ принят, ожидает подтверждения»).
Очередь сообщений
Главный инструмент асинхронного обмена — очередь сообщений. В ней три участника:
- отправитель (producer) — система, которая кладёт сообщение;
- брокер (broker) — отдельная программа-посредник, которая хранит сообщения, пока их не заберут; аналогия — почтовое отделение;
- получатель (consumer) — система, которая забирает сообщения и обрабатывает их.
flowchart LR
Shop["Интернет-магазин<br/>(отправитель)"] -->|"сообщение: заказ оплачен"| Broker["Брокер<br/>очередь заказов"]
Broker -->|"забирает, когда готов"| Wms["Склад<br/>(получатель)"]
Wms -.->|"подтверждение обработки"| Broker
Почему сообщение не теряется, если склад недоступен? Потому что магазин отправляет его не складу, а брокеру. Брокер сохраняет сообщение — при надёжной настройке на диск, а не только в память, — и держит его, пока получатель не заберёт и не подтвердит, что обработал. Склад перезапустился через час — и разбирает накопившиеся сообщения. Если склад взял сообщение, но упал, не подтвердив, брокер отдаст его снова.
Отсюда важное следствие: получатель может получить одно и то же сообщение дважды. Это не сбой, а нормальное поведение надёжной доставки, и получатель должен быть к нему готов (об этом — в разделе про идемпотентность).
Названия брокеров, которые вы услышите: RabbitMQ, Apache Kafka, облачные очереди. Чем они различаются, разбирается в модуле Б.5.
Вебхуки
Допустим, магазину нужно знать, когда служба доставки вручила посылку. Первый способ — опрос (polling): магазин каждые пять минут спрашивает «что с посылкой 7781?». Большинство ответов — «ничего не изменилось», запросов много, а узнаёт магазин о событии с задержкой до пяти минут.
Второй способ — вебхук (webhook): магазин заранее даёт службе доставки свой адрес, например https://shop.example/hooks/delivery, и служба сама отправляет туда HTTP-запрос, когда что-то произошло. Это «обратный звонок»: не вы звоните каждые пять минут, а вам звонят, когда есть новости.
Вебхук удобнее опроса: события приходят сразу, лишних запросов нет. Но у него свои вопросы, которые аналитик должен закрыть:
- Как убедиться, что запрос пришёл действительно от службы доставки, а не от злоумышленника? Обычно запрос подписывают: отправитель вычисляет по содержимому запроса и секретному ключу, известному только двум сторонам, контрольную строку (подпись), а получатель пересчитывает её и сравнивает.
- Что будет, если магазин в момент события недоступен? Хорошие поставщики повторяют отправку несколько раз — значит, возможны дубли.
- Гарантирован ли порядок? Событие «вручено» может прийти раньше, чем «передано курьеру».
- Что если все повторы исчерпаны? Нужен запасной способ — например, периодическая сверка через API.
Файловый обмен и пакетные выгрузки
Не всё передаётся по одному сообщению. Бухгалтерии не нужна каждая продажа в момент продажи — ей нужен реестр продаж за день. Такой обмен называют пакетным (batch): данные копятся и передаются одним большим куском по расписанию.
Типичный сценарий: каждую ночь в 02:00 магазин формирует файл sales_2026-09-26.csv со всеми продажами за сутки и кладёт его в условленный каталог. Бухгалтерская система в 03:00 забирает файл и загружает. Каталог может быть общей сетевой папкой или SFTP-сервером — сервером для передачи файлов по защищённому соединению.
Пакетный обмен всё ещё повсюду: с банками, государственными и старыми учётными системами. Он прост, выдерживает большие объёмы и не требует, чтобы обе системы были доступны одновременно. Зато данные приходят с задержкой, а ошибка в одной строке может остановить загрузку всего файла.
В постановке аналитик фиксирует: правило именования, формат и кодировку, расписание, что делать с файлом после загрузки, как отправитель узнаёт об ошибке, что делать с повторно выложенным файлом и как понять, что файл выложен целиком, а не наполовину (например, файл-флаг после основного или запись под временным именем с переименованием).
Почему нельзя лезть в чужую базу данных
Самый быстрый способ интеграции на вид — дать складу доступ к базе данных магазина: пусть сам читает таблицу заказов. Никаких API, никаких очередей. Это почти всегда плохая идея, и вот почему:
- Таблицы становятся контрактом. Команда магазина переименовала столбец или разделила таблицу на две — и склад сломался, хотя его никто не трогал. Внутренняя структура базы превращается в публичное обещание, которое никто не давал.
- Бизнес-правила обходятся. Магазин считает заказ готовым к сборке, только если оплата подтверждена и нет блокировки по антифроду (проверке на мошенничество). Склад, читая таблицу напрямую, этих правил не знает и соберёт неоплаченный заказ.
- Нагрузка. Тяжёлый запрос склада может замедлить базу магазина в час пик.
- Безопасность. Склад видит данные, которые ему не нужны: телефоны, адреса, платежи.
- Непонятно, кто отвечает. Когда что-то сломалось, каждая команда уверена, что проблема на другой стороне.
API или сообщение — это витрина, которую владелец системы сознательно поддерживает. База — склад за витриной, куда посторонним нельзя.
Ошибки, повторы и идемпотентность
Разберём самый важный сценарий. Магазин отправил в платёжный шлюз запрос «списать 3980 рублей за заказ 1045». Прошло 30 секунд — ответа нет. Магазин прервал ожидание: сработал таймаут (timeout, максимальное время ожидания ответа).
Что произошло? Возможны три варианта, и магазин не знает, какой из них случился:
- Запрос не дошёл до шлюза — деньги не списаны.
- Запрос дошёл, шлюз списал деньги, но ответ потерялся по дороге.
- Шлюз ещё обрабатывает запрос и спишет деньги через минуту.
sequenceDiagram
participant Shop as Интернет-магазин
participant Pay as Платёжный шлюз
Shop->>Pay: Списать 3980 руб., ключ K-1045-1
Note over Pay: Деньги списаны
Pay--xShop: Ответ потерян в сети
Note over Shop: Таймаут, результат неизвестен
Shop->>Pay: Повтор с тем же ключом K-1045-1
Pay-->>Shop: Уже выполнено, вот результат первой операции
Если просто повторить запрос, во втором и третьем случае покупатель заплатит дважды. Если не повторять, в первом случае заказ останется неоплаченным. Главное правило: после таймаута результат неизвестен, а не отрицателен.
Решение — идемпотентность (idempotency). Операция идемпотентна, если выполнить её один раз или десять раз — результат одинаковый. Кнопка вызова лифта идемпотентна: нажмёте её пять раз — лифт приедет один раз. Кнопка «перевести 100 рублей» без специальной защиты — нет.
Как сделать списание идемпотентным: магазин при первом запросе генерирует уникальный ключ идемпотентности (в примере — K-1045-1) и повторяет запрос с тем же ключом. Шлюз запоминает ключи уже выполненных операций: если ключ видит впервые — списывает, если повторно — не списывает, а возвращает результат первой операции. Многие платёжные API поддерживают такой ключ; аналитику нужно проверить это в документации и явно записать в постановке.
Кроме того, повторять стоит не сразу и не бесконечно — например, три попытки с растущими паузами, после чего заказ переходит в состояние «требует проверки». Если шлюз умеет отвечать на вопрос «что с операцией по заказу 1045?», сначала спросить статус. И раз в сутки сверять свои оплаты с реестром шлюза.
Та же логика действует для очередей и вебхуков: раз дубли возможны, получатель должен распознавать повтор — по идентификатору сообщения или по бизнес-ключу (номер заказа плюс тип события) — и не выполнять действие дважды.
Что писать в спецификации интеграции
Спецификация интеграции — документ, по которому две команды делают свои части и потом проверяют, что они стыкуются. Минимальный состав:
| Раздел | Что в нём |
|---|---|
| Участники | Системы, их владельцы, кто инициатор, кто отвечает за сбои |
| Назначение | Какую бизнес-задачу решает обмен, какие процессы от него зависят |
| Способ | Синхронный API, очередь, вебхук, файл; почему выбран именно он |
| Сценарии | Основной поток по шагам; альтернативные потоки; диаграмма последовательности |
| Формат | Структура сообщения или файла, типы, обязательность, примеры; маппинг полей: какое поле источника в какое поле приёмника и с каким преобразованием |
| Ошибки | Перечень ошибок, коды, что делает каждая сторона, политика повторов, идемпотентность, куда пишется журнал и кто получает оповещение |
| Нефункциональные требования | Объёмы (сообщений в час, строк в файле), допустимое время ответа, расписание, доступность, безопасность (аутентификация, шифрование, персональные данные) |
| Открытые вопросы | Что не согласовано и с кем |
Проверка готовности: разработчик каждой стороны может по документу ответить, что делает его система, если соседняя молчит, отвечает ошибкой или присылает дубль.
Разобранный пример: как выбрать способ
Сведём варианты для интернет-магазина в одну карту. Это не единственно верный ответ — в реальном проекте выбор зависит ещё и от того, что умеют соседние системы.
| Связь | Инициатор | Данные | Способ | Почему |
|---|---|---|---|---|
| Магазин → склад: проверка остатка | Магазин | Товар, количество | Синхронный API | Нужен ответ до оформления заказа |
| Магазин → склад: заказ на сборку | Магазин | Заказ с позициями | Очередь | Ответ сразу не нужен, склад не должен блокировать продажи |
| Магазин → платёжный шлюз: оплата | Магазин | Сумма, заказ, ключ идемпотентности | Синхронный API | Покупатель ждёт результата |
| Платёжный шлюз → магазин: итог оплаты | Шлюз | Статус операции | Вебхук | Некоторые оплаты подтверждаются не сразу |
| Служба доставки → магазин: статусы | Служба доставки | Трек-номер, статус | Вебхук, плюс сверка через API | События редкие, нужна быстрая реакция |
| Магазин → бухгалтерия: продажи | Магазин | Реестр за сутки | Файл по расписанию | Нужен итог за день, большой объём |
| Магазин → рассылки: письмо | Магазин | Адрес, шаблон, данные | Очередь | Письмо может уйти через минуту |
Что дальше
Здесь остались за кадром детали контрактов API: пагинация, формат ошибок, версии и совместимость — их разбирает модуль Б.3. Виды брокеров, гарантии доставки и порядок сообщений — предмет модуля Б.5, а подробно — модуля 3.4. Пакетные интеграции с их контролем полноты и повторной загрузкой разобраны в модуле 8.4. Как оформить сценарии интеграции диаграммами, покажет следующий модуль А.7.
Типичные ошибки
- Описывать только успешный сценарий. Таймауты, дубли и недоступность соседа не попадают в постановку — и каждый разработчик обрабатывает их по-своему.
- Считать таймаут отказом. После таймаута операция могла выполниться; повтор без ключа идемпотентности приводит к двойному списанию или двойному заказу.
- Делать синхронным всё подряд. Цепочка из нескольких синхронных вызовов останавливается, если упало любое звено.
- Предлагать интеграцию через прямое чтение чужой базы «на время». Временные решения живут годами, и потом их никто не может изменить.
- Не указывать объёмы и частоту. «Выгружать продажи» без цифр не позволяет выбрать способ и проверить нагрузку.
- Забыть про приёмку файла целиком. Получатель начинает читать файл, который ещё пишется, и загружает половину данных.
- Не назначить ответственного за сбой. Ошибка в журнале есть, но оповещение никому не приходит.
Как говорить об этом на собеседовании
На собеседовании на позицию junior или middle системного аналитика часто дают задачу: «Опишите интеграцию магазина с платёжной системой» или «Какие способы интеграции вы знаете?». Сильный ответ не перечисляет технологии, а начинается с вопросов: кто инициатор, нужен ли ответ сразу, какие объёмы, что при сбое. Выбор способа объясняйте через компромисс: синхронный вызов проще, но связывает системы; очередь развязывает, но добавляет промежуточные состояния.
Обязательно проговорите сценарий «запрос ушёл, ответ не пришёл»: результат неизвестен, повторяем с ключом идемпотентности, попытки исчерпаны — уточняем статус и сверяем. Это показывает, что вы думаете о надёжности, а не только об основном потоке. Про прямой доступ к базе объясняйте через контракт и обход бизнес-правил, а не через «так не принято».
Коротко
- Любая интеграция начинается с четырёх вопросов: кто инициатор, какие данные, как часто, что при ошибке.
- REST API — это ресурсы, методы, коды ответа и JSON; коды 4xx говорят «исправь запрос», 5xx — «попробуй позже».
- Синхронно — когда ответ нужен сейчас; асинхронно — когда достаточно, что сообщение принято.
- Брокер хранит сообщение, пока получатель его не обработает; обратная сторона надёжности — возможные дубли.
- Вебхук избавляет от постоянного опроса, но требует проверки подписи, обработки повторов и запасной сверки.
- Файловый обмен жив и нужен для больших объёмов по расписанию; важно описать формат, расписание и признак готовности файла.
- В чужую базу напрямую не ходят: таблицы становятся контрактом, бизнес-правила обходятся.
- После таймаута результат неизвестен; повтор безопасен только для идемпотентной операции.
Читать дальше
- Документация Swagger: «What is OpenAPI?».
- Грегор Хоп, Бобби Вульф, «Шаблоны интеграции корпоративных приложений» — введение и первые главы (без глубины).
На system-design.space:
Практика
- Для обезличенного интернет-магазина составить карту интеграций: склад, платёжный шлюз, служба доставки, бухгалтерия, рассылки. Для каждой указать инициатора, данные, способ и частоту обмена.
- Открыть документацию любого публичного API в формате Swagger (например, Petstore) и описать своими словами один метод: запрос, ответ, возможные ошибки.
- Для одной интеграции выписать сценарии сбоев (получатель недоступен, ответ не пришёл, пришёл дубль) и что система должна делать в каждом случае.
Вопросы для самопроверки
- Какие способы интеграции вы знаете и когда выбрать каждый?
- Чем синхронный вызов отличается от асинхронного обмена через очередь?
- Почему нельзя интегрироваться через прямой доступ к базе другой системы?
- Запрос на оплату ушёл, ответ не пришёл. Что делать?
- Что обязательно должно быть в спецификации интеграции?
- Что такое вебхук и чем он удобнее периодического опроса?