Course contentsShow
← Node.js
Lesson 696 of 1,9807. Web Framework Architecture and MiddlewareFree lesson

Aggregated Data Responses

Compose complex API responses by querying multiple domain services in parallel.

In this lesson, you will learn how to improve API performance by fetching data from multiple internal domain services concurrently to build a single, unified response.

Why Aggregate?

In a modular Node.js architecture using Service Layer Abstraction and Domain Entity Modeling, your data is often spread across different services (e.g., a User service, an Order service, and a Product service). If you fetch these sequentially—waiting for the User service to return before calling the Order service—you introduce "waterfall latency," where each round-trip adds to the user's wait time.

Instead, we use Aggregated Data Responses to fire these requests in parallel, significantly reducing the total response time to the duration of the slowest single request.

Implementing Parallel Aggregation

The cleanest way to achieve this in Node.js is using Promise.all(). This allows multiple asynchronous repository calls to run simultaneously.

Imagine we are building a dashboard endpoint that needs both user profile info and recent order history:

async function getUserDashboard(userId) {
  // Trigger both service calls in parallel
  const [userProfile, userOrders] = await Promise.all([
    userService.getById(userId),
    orderService.getByUserId(userId)
  ]);

  // Combine results into a single domain entity response
  return {
    ...userProfile,
    recentOrders: userOrders,
    generatedAt: new Date()
  };
}

Strategic Considerations

When aggregating data, keep these principles in mind:

  1. Error Handling: Promise.all fails fast. If one service call rejects, the whole request fails. If you want a "partial success" (e.g., show the user profile even if orders fail), consider Promise.allSettled() instead.
  2. Resource Management: Because you are now hitting multiple services at once, ensure your Rate Limiting with Redis and Backpressure Management are robust. You are effectively multiplying the load on your internal services for every single inbound request.
  3. Data Integrity: Ensure the aggregated response adheres to your Value Object Validation rules before sending it back to the client.

By decoupling the data fetching logic and executing it in parallel, you move from a slow, blocking architecture to a high-performance, concurrent API layer.

Key Takeaway: Use Promise.all() to trigger independent domain service requests simultaneously, minimizing total latency by collapsing multiple network round-trips into a single wait period.