Bird
Raised Fist0
Microservicessystem_design~7 mins

Request aggregation in Microservices - System Design Guide

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Problem Statement
When a client needs data from multiple microservices, making separate calls to each service causes high latency and complex client logic. This leads to slow responses and increased network overhead, degrading user experience.
Solution
Request aggregation collects data from multiple microservices on the server side and combines it into a single response. The client sends one request to an aggregator service, which calls the required microservices in parallel or sequence, then merges their results before replying.
Architecture
Client
Aggregator
Microservice 2

This diagram shows the client sending one request to the aggregator service, which then calls multiple microservices and combines their responses before replying to the client.

Trade-offs
✓ Pros
Reduces client complexity by centralizing multiple calls into one.
Decreases overall latency by parallelizing requests inside the aggregator.
Minimizes network overhead with fewer client-server round trips.
Allows centralized caching and response shaping.
✗ Cons
Aggregator can become a bottleneck or single point of failure.
Increases complexity in the aggregator service logic.
Harder to maintain if microservices change frequently.
Use when clients need data from multiple microservices frequently and low latency is critical, typically at scale above hundreds of requests per second.
Avoid if the system has very simple data needs or very low traffic (under 100 req/sec), where added aggregator complexity outweighs benefits.
Real World Examples
Netflix
Netflix uses request aggregation in their API gateway to combine data from multiple backend services into a single response for the client app, reducing latency and simplifying client logic.
Uber
Uber aggregates data from different microservices like driver location, pricing, and trip details into one response to provide a seamless user experience in their app.
Amazon
Amazon's frontend aggregates inventory, pricing, and recommendation microservices to present a unified product page quickly.
Code Example
The before code shows the client making two separate calls and merging data. The after code moves this logic to an aggregator service that calls microservices in parallel and returns combined data, simplifying the client.
Microservices
### Before: Client calls microservices separately
import requests

def get_user_profile(user_id):
    user = requests.get(f'http://user-service/users/{user_id}').json()
    orders = requests.get(f'http://order-service/orders?user={user_id}').json()
    return {'user': user, 'orders': orders}

### After: Client calls aggregator once
import requests

def get_user_profile(user_id):
    response = requests.get(f'http://aggregator-service/profile/{user_id}')
    return response.json()

# Aggregator service example
from flask import Flask, jsonify
import requests
import concurrent.futures

app = Flask(__name__)

@app.route('/profile/<user_id>')
def profile(user_id):
    with concurrent.futures.ThreadPoolExecutor() as executor:
        user_future = executor.submit(requests.get, f'http://user-service/users/{user_id}')
        orders_future = executor.submit(requests.get, f'http://order-service/orders?user={user_id}')
        user = user_future.result().json()
        orders = orders_future.result().json()
    return jsonify({'user': user, 'orders': orders})
OutputSuccess
Alternatives
API Gateway
API Gateway routes requests but may not aggregate responses; request aggregation combines multiple service responses into one.
Use when: Choose API Gateway when routing and authentication are primary needs without complex data merging.
Backend for Frontend (BFF)
BFF is a specialized aggregator tailored per client type (mobile, web), while request aggregation can be generic.
Use when: Choose BFF when different clients require different data shapes or aggregation logic.
Client-side aggregation
Client makes multiple calls and merges data locally, unlike server-side aggregation which centralizes it.
Use when: Choose client-side aggregation for simple apps with low latency tolerance and fewer microservices.
Summary
Request aggregation prevents high latency and complex client logic by combining multiple microservice calls into one server-side request.
It reduces network overhead and simplifies clients by centralizing data fetching and merging in an aggregator service.
This pattern is best for systems with multiple microservices and high request volumes needing low latency responses.

Practice

(1/5)
1. What is the main purpose of request aggregation in microservices?
easy
A. To cache responses from a single microservice
B. To split a large service into smaller microservices
C. To handle database transactions across services
D. To combine data from multiple microservices into a single response

Solution

  1. Step 1: Understand request aggregation concept

    Request aggregation means collecting data from multiple microservices to form one combined response.
  2. Step 2: Identify the main goal

    The goal is to reduce multiple client calls into one, improving efficiency and user experience.
  3. Final Answer:

    To combine data from multiple microservices into a single response -> Option D
  4. Quick Check:

    Request aggregation = combine multiple responses [OK]
Hint: Aggregation means combining multiple service responses [OK]
Common Mistakes:
  • Confusing aggregation with service splitting
  • Thinking it only caches data
  • Mixing aggregation with transaction management
2. Which of the following is the correct way to implement a request aggregator in a microservices architecture?
easy
A. Make parallel calls to all required microservices and aggregate responses asynchronously
B. Make sequential calls to each microservice and combine results synchronously
C. Call only one microservice and ignore others
D. Use a database trigger to combine data from microservices

Solution

  1. Step 1: Review aggregator call patterns

    Efficient aggregators call multiple services in parallel to reduce total wait time.
  2. Step 2: Identify correct implementation

    Parallel asynchronous calls improve performance and user experience compared to sequential calls.
  3. Final Answer:

    Make parallel calls to all required microservices and aggregate responses asynchronously -> Option A
  4. Quick Check:

    Parallel async calls = best aggregator practice [OK]
Hint: Use parallel async calls for faster aggregation [OK]
Common Mistakes:
  • Using sequential calls causing slow responses
  • Ignoring some microservices in aggregation
  • Trying to use database triggers for aggregation
3. Consider this pseudocode for a request aggregator:
async function aggregate() {
  const user = await getUser();
  const orders = await getOrders(user.id);
  const payments = await getPayments(user.id);
  return { user, orders, payments };
}
What is the main problem with this code?
medium
A. It does not handle errors from getUser
B. It calls getOrders and getPayments sequentially, increasing total response time
C. It returns data in the wrong format
D. It calls getUser multiple times unnecessarily

Solution

  1. Step 1: Analyze call sequence

    The code waits for getUser, then calls getOrders and waits, then calls getPayments and waits, all sequentially.
  2. Step 2: Identify inefficiency

    Calling getOrders and getPayments one after another increases total wait time unnecessarily.
  3. Final Answer:

    It calls getOrders and getPayments sequentially, increasing total response time -> Option B
  4. Quick Check:

    Sequential calls = slower aggregation [OK]
Hint: Parallelize independent calls to reduce wait time [OK]
Common Mistakes:
  • Assuming error handling is missing
  • Thinking return format is incorrect
  • Believing getUser is called multiple times
4. You have a request aggregator that calls three microservices in parallel. Sometimes, one service fails and causes the whole aggregation to fail. How can you fix this?
medium
A. Cache the failed service response permanently
B. Retry the failed service indefinitely until it succeeds
C. Ignore errors and return partial data with error info for failed services
D. Stop calling other services if one fails

Solution

  1. Step 1: Understand error impact in aggregation

    If one service fails, the aggregator should still return available data to avoid full failure.
  2. Step 2: Choose error handling strategy

    Returning partial data with error info improves user experience and system resilience.
  3. Final Answer:

    Ignore errors and return partial data with error info for failed services -> Option C
  4. Quick Check:

    Partial data + error info = robust aggregation [OK]
Hint: Return partial results with errors, don't fail whole aggregation [OK]
Common Mistakes:
  • Retrying endlessly causing delays
  • Stopping all calls on one failure
  • Caching errors permanently causing stale data
5. You design a request aggregator for a shopping app that calls user, orders, and payment microservices. To improve scalability, which design choice is best?
hard
A. Use asynchronous parallel calls with timeout and fallback data for each microservice
B. Call microservices sequentially and cache all responses for 24 hours
C. Aggregate data in a single monolithic service instead of microservices
D. Make synchronous calls and block until all microservices respond

Solution

  1. Step 1: Consider scalability needs

    Parallel async calls reduce latency and improve throughput under load.
  2. Step 2: Add timeout and fallback

    Timeouts prevent long waits; fallback data keeps user experience smooth if a service is slow or down.
  3. Step 3: Evaluate other options

    Sequential calls and long caching reduce freshness and responsiveness; monolith loses microservices benefits; synchronous blocking hurts scalability.
  4. Final Answer:

    Use asynchronous parallel calls with timeout and fallback data for each microservice -> Option A
  5. Quick Check:

    Async parallel + timeout + fallback = scalable aggregator [OK]
Hint: Combine async calls with timeout and fallback for best scalability [OK]
Common Mistakes:
  • Using sequential calls causing slow response
  • Relying on stale cached data too long
  • Ignoring microservices benefits by monolith design