API и интеграции

3 мин чтения ·

API Composition: клиент покупает услугу, а не знает ваши микросервисы

Один экран заказа требует данные из нескольких систем. Почему клиент не должен собирать их сам — и что делать, если один источник не ответил?

Покупатель открывает заказ. Ему нужны стоимость, состав покупки, статус оплаты и дата доставки. Для компании это четыре разных области ответственности; иногда каждая живёт в своём сервисе. Покупателю же нужен один понятный экран, а не экскурсия по внутренней архитектуре.

Если мобильное приложение самостоятельно обращается к нескольким системам, оно начинает разбираться в их адресах, правилах, ошибках и несовместимых изменениях. Это называется независимостью микросервисов, но для клиентской команды часто выглядит как дополнительная работа за чужой счёт.

Собрать продуктовый ответ на стороне сервера

API Composition переносит сбор данных в отдельный компонент. Клиент спрашивает: «покажи заказ». Композиционный слой запрашивает необходимые сведения у внутренних сервисов, объединяет их и возвращает контракт, созданный для конкретного экрана или внешнего потребителя.

Часть вызовов можно выполнять параллельно. Это может сократить ожидание на клиенте, особенно если раньше он последовательно обращался к нескольким системам через сеть с высокой задержкой. Однако зависимостей внутри сервера не становится меньше. Они просто спрятаны за осмысленной продуктовой границей.

Композиция может находиться в BFF, отдельном агрегаторе или иногда в API Gateway. Но тяжёлую бизнес-оркестрацию лучше не превращать в обязательную часть маршрутизации всех запросов. Чем больше обязанностей у центрального узла, тем выше его собственная цена отказа.

Один источник не ответил. Что покажем клиенту?

На экране заказа нет рекомендаций похожих товаров. Неприятно, но оформление покупки можно продолжить. А если не получено подтверждение оплаты? Делать вид, что всё хорошо, уже опасно.

Поэтому композиционный слой должен знать, какие данные обязательны, а какие допустимо временно опустить. Иногда уместен частичный ответ с явным состоянием отсутствующих данных. Иногда нужно вернуть ошибку и не обещать клиенту завершённую операцию.

Важны таймауты, ограничение одновременных обращений, трассировка каждого внутреннего вызова и правила деградации. Иначе один медленный участник задержит весь внешний запрос, а найти виновника окажется трудно.

Согласованность данных тоже не появляется от того, что ответы склеили в один объект. Статус оплаты и доставки могли быть получены в разные моменты. Если нужно гарантировать единый снимок состояния, простого API Composition недостаточно.

Кто владеет последним контрактом?

Именно здесь часто возникает новая организационная проблема. Вроде бы клиент избавился от знания внутренних сервисов, но теперь для каждой доработки должен обращаться в центральную команду агрегатора. Вместо семи API появилась одна очередь согласований.

Я бы заранее договорился, кто отвечает за внешний продуктовый контракт, кто меняет состав ответа и кто имеет право определять fallback. Сам агрегатор не должен произвольно менять бизнес-правила: считать скидку, разрешать возврат или подтверждать платёж — ответственность доменных систем.

Когда не стоит добавлять ещё один слой

Если экрану требуется один сервис и пара простых полей, дополнительная композиция не нужна. Если задача только в объединении нескольких запросов к одной базе, иногда дешевле улучшить исходный endpoint. Выигрыш нужно оценивать по задержке, сложности клиентского кода и количеству согласований.

Gateway Aggregation в Azure Architecture Center разбирает те же компромиссы: параллельные вызовы, таймауты, частичные ответы и цену промежуточного компонента.

API Composition полезен, когда клиенту нужен цельный продуктовый сценарий, а компании — свобода менять внутренние сервисы. Но внутреннюю сложность нельзя просто спрятать: кто-то должен управлять ею и отвечать за результат.