Aggregator
The Aggregator pattern calls multiple services and merges their responses into one result, reducing client round-trips. It underpins API composition, gateway aggregation, and backends-for-frontends.
The Aggregator pattern collects data or results from several services and merges them into one response. Clients that would otherwise make many calls and stitch the results themselves instead make a single call to the aggregator. It is a foundational composition pattern in distributed systems and a common building block of gateways and backends-for-frontends.
How It Works
The aggregator receives a request, fans out to the relevant downstream services (often in parallel to minimize latency), waits for their responses, and combines them into a single payload. Combination can be a simple merge, a join on shared keys, or a computed summary. The aggregator typically applies a timeout and decides how to handle partial failures, returning what it has or failing the whole request depending on requirements.
The aggregator may be a standalone service, embedded in an API gateway, or part of a BFF tailored to a specific client.
The aggregator should set an overall deadline and per-dependency timeouts, then assemble whatever responses arrived by the deadline. Caching individual sub-responses and coalescing duplicate in-flight calls can sharply reduce load on downstream services. When responses share keys, the merge becomes a join; when they are independent sections of a view, it is a simple composition into one envelope.
When to Use It
Use an aggregator when a client needs a consolidated view assembled from multiple services, when you want to cut chatty client round-trips, or when several independent calls can run in parallel and be merged. It is especially useful for dashboards and detail screens that draw on many sources.
If only one service holds the data, no aggregator is needed; if the join is heavy and frequent, a precomputed read model may serve better.
It is also useful as a stable seam in front of evolving services: clients depend on the aggregator's contract while the services behind it are split, merged, or replaced.
Trade-offs
The aggregator reduces client complexity and round-trips but becomes a coupling point that must know about each downstream service. It is only as fast as its slowest dependency unless it degrades gracefully, so timeouts and partial-result strategies are essential. It adds another component to deploy and operate. The healthiest aggregators stay thin, owning fan-out, timeouts, and merging, while deliberately keeping business rules in the services they call so they do not slowly accrete logic that belongs elsewhere.
Related Patterns
API Composition is the aggregator used for cross-service queries. Gateway Aggregation places it at the gateway. Scatter-Gather is the messaging variant that broadcasts and collects replies. A Backend for Frontend is often an aggregator tuned per client. Scatter-Gather generalizes it to broadcast-and-collect over messaging channels.
Example
A travel app's trip screen shows flights, hotels, and car rentals from three services. The mobile client calls one aggregator endpoint. The aggregator issues three parallel requests with a 700 ms timeout, merges the responses into one trip object, and returns it. If the car service is slow, the aggregator returns flights and hotels and omits cars, keeping the screen responsive.