Prompt

How do I aggregate APIs from multiple microservices?

Technology · Developer Tools / Developer tools2 observationsLast seen Jul 15, 2026

Latest observation

Jul 15, 2026 · Claude

Here's how to approach aggregating APIs from multiple microservices:

Core patterns for aggregation

  • API composition (aggregator service) — a dedicated service or endpoint calls multiple downstream services in parallel, then merges results into one response. This is the most direct answer to "aggregate APIs" — best for real-time reads across 2-4 services.
  • BFF (Backend for Frontend) — client-specific aggregation layer when different consumers (web, mobile, partner) need different shapes of the combined data, not just the same merge for everyone.
  • GraphQL federation — multiple services each expose a partial schema; a federation gateway (Apollo Federation, GraphQL Mesh) stitches them into one queryable schema, letting clients request exactly the combination of fields they need without you hand-building every aggregation endpoint.
  • CQRS + materialized views — instead of aggregating live on every request, build a denormalized read model ahead of time via events, and serve reads from that single, pre-joined source. Best when live aggregation would be too slow or you have high read volume.

Implementation approach for live aggregation

  • Call downstream services in parallel, not sequentially — if you need data from Orders, Users, and Inventory, fire all three requests concurrently (Promise.all in Node.js, asyncio.gather in Python, goroutines + WaitGroup in Go) rather than awaiting one after another. Sequential calls compound latency unnecessarily.
  • Set a timeout per downstream call — decide explicitly what happens if one service is slow: does the whole aggregation fail, or do you return partial data with that section omitted/marked unavailable? Don't let this be accidental.
  • Merge and reshape the response — combine the results into the shape your client actually needs, not just a raw concatenation of each service's response format.
  • Cache aggressively where data doesn't change often — especially valuable when the same aggregation gets requested repeatedly (e.g., a product page combining pricing, inventory, and reviews).
  • Handle partial failure explicitly — a common approach is returning a 200 with a partial: true flag and per-section status, rather than failing the entire request because one non-critical service was down.

Where to put the aggregation logic

  • API gateway with aggregation plugins — some gateways (Kong, Apigee) support basic request aggregation, but this is generally discouraged for anything beyond trivial merges — business logic in the gateway is hard to test, version, and reason about.
  • Dedicated aggregator/BFF service — the more maintainable choice; keeps the gateway thin (routing/auth/rate limiting only) and puts composition logic somewhere it can be properly tested and versioned.
  • GraphQL federation layer — best when the aggregation needs vary a lot by consumer/query rather than being one fixed shape.

Avoiding common pitfalls

  • Don't let the aggregator become a place where business logic accumulates — it should combine and shape data, not make business decisions. Decisions belong in the owning services.
  • Watch for the "N+1" problem — if aggregating a list (e.g., 50 orders) requires a separate call per item to another service, batch those into one call (getUsersByIds([...])) instead of looping calls one at a time.
  • Avoid tight coupling to internal service structure — the aggregator's output contract should be stable for clients even if the internal services it calls change.
  • If write operations are involved (not just reads), you're likely in saga/orchestration territory rather than simple aggregation — different pattern, different failure-handling requirements (compensating actions, not just partial responses).

How to choose an approach

Simple, fixed combination of 2-4 services, one shape needed → aggregator/API composition service.

Different clients need different shapes of the same underlying data → BFF.

Clients need flexible, ad-hoc combinations of fields across services → GraphQL federation.

High read volume, some staleness acceptable → CQRS + event-driven materialized views instead of live aggregation.

  • Practical baseline: for most teams, a dedicated aggregator or BFF service that calls downstream services in parallel with per-call timeouts, explicit partial-failure handling, and response caching covers the vast majority of real-world aggregation needs — reach for GraphQL federation or CQRS only when the simpler pattern genuinely doesn't fit (very flexible querying needs, or read volume that live aggregation can't handle).

Observation history

See 1 earlier observation

Create a free Obsurfable account to unlock historical responses, model comparisons, and deeper brand intelligence.

How did Obsurfable measure this prompt?

Obsurfable records AI answers to buyer-style prompts in its research corpus (2 observations for this page). Metrics are distributions over observations, not a single static ranking.

Which AI systems does Obsurfable collect answers from?

OpenAI, ChatGPT, Google, Gemini, Google AI Mode, Anthropic, Claude, Perplexity, Grok, DeepSeek, Mistral, Copilot, and Meta AI.