Что такое паттерн API Composition?

«Что такое паттерн API Composition?» — вопрос из категории Архитектура, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

API Composition — это паттерн интеграции в микросервисной архитектуре, при котором агрегатор (композитор) выполняет несколько параллельных или последовательных вызовов к другим сервисам для объединения их данных в единый ответ для клиента.

Зачем он нужен? Чтобы избежать множественных сетевых вызовов со стороны клиента, уменьшить задержку и скрыть внутреннюю сложность системы.

Пример реализации на Java с Spring:

@RestController
public class OrderDetailsController {
    @Autowired
    private OrderServiceClient orderService;
    @Autowired
    private UserServiceClient userService;
    @Autowired
    private ProductServiceClient productService;

    @GetMapping("/order-details/{orderId}")
    public OrderDetails getOrderDetails(@PathVariable String orderId) {
        // Параллельные или последовательные вызовы к микросервисам
        CompletableFuture<Order> orderFuture = orderService.getOrderAsync(orderId);
        CompletableFuture<User> userFuture = orderFuture.thenCompose(order -> 
            userService.getUserAsync(order.getUserId())
        );
        CompletableFuture<Product> productFuture = orderFuture.thenCompose(order ->
            productService.getProductAsync(order.getProductId())
        );

        // Ожидание и композиция результатов
        return CompletableFuture.allOf(orderFuture, userFuture, productFuture)
                .thenApply(v -> new OrderDetails(
                    orderFuture.join(),
                    userFuture.join(),
                    productFuture.join()
                )).join();
    }
}

Преимущества:

  • Уменьшает количество клиентских запросов и сетевых round-trips.
  • Предоставляет клиенту готовый, агрегированный ответ.
  • Централизует логику композиции и обработки ошибок.

Недостатки и риски:

  • Точка отказа: Композитор становится критическим узлом.
  • Сложность: Необходимо обрабатывать частичные сбои (например, с помощью паттернов Circuit Breaker, Fallback).
  • Производительность: Общее время ответа равно времени самого медленного вызова + накладные расходы.

Альтернативы: Для сложных сценариев агрегации данных рассмотрите GraphQL (единая конечная точка с гибкими запросами) или CQRS (отдельная модель для чтений).