Bootstrap Service: Aggregate Downstream Services and Return the Right HTTP Status

Quick Overview

Implement a bootstrap service that calls several independent downstream services concurrently, aggregates their data into one response for a client app, and returns an HTTP status code that reflects partial or total failure. It tests concurrent calls, timeouts, per-section error reporting, and mapping downstream failures to client-facing status codes.

Bootstrap Service: Aggregate Downstream Services and Return the Right HTTP Status

Company: DoorDash

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Onsite

A client app makes a single "bootstrap" request, typically when it starts, and expects one response containing everything it needs to render its first screen. That data lives in several independent downstream services, so the backend needs a `BootstrapService` that calls those services, aggregates their data into one response body, and returns that body with an HTTP status code. Assume each downstream service is reached through a client that returns a response with an HTTP status code and a JSON body, or raises an exception when the call cannot complete (for example, a connection error). As an illustration, the bootstrap payload might combine a user-profile service, an app-configuration service and a promotions service. ### Constraints and Clarifications - The downstream services are independent: no call needs another call's result. - A downstream call can succeed, return an error status (4xx or 5xx), be slow, or fail at the connection level. - The caller of the bootstrap endpoint sees only the one aggregated response: its status code and its body. ### Clarifying Questions - Are some services required for the app to work at all, while others are optional sections that may be missing? - If an optional service fails, should the overall response still succeed, and how should the body tell the client which sections are missing? - When a required service fails, should a caller-caused error from that service (such as an authentication failure) be passed through, and which code should represent a downstream outage or timeout? - Is there a latency budget for the whole bootstrap call, and should each downstream service have its own timeout? - Should failed downstream calls be retried within the same request? - Does the client need per-section status information, or only an overall status code? ### Part 1 — Aggregate the downstream data Implement `BootstrapService` with a method that, given the requesting user's ID, calls every downstream service and returns one response whose body contains each service's data under its own key. For this part, assume every downstream call succeeds. ```hint Where the latency goes The app is waiting on this endpoint. Compare the endpoint's latency when the services are called one after another with the latency when they are called at the same time. ``` #### What This Part Should Cover - A clear interface for a downstream service and for the aggregated response - Concurrent downstream calls, with the resulting end-to-end latency analyzed - A response format that new services can join without changing its structure ### Part 2 — Add HTTP response status handling Now downstream calls can fail. Extend the service so that the aggregated response carries an HTTP status code that accurately reflects what happened, and so that the body tells the client what happened to each section. Explain which status code you return in each situation, and why. ```hint Classify outcomes first Before choosing codes, list the distinct things that can happen to a single downstream call, and decide which of them should fail the whole request. ``` ```hint Whose problem is it A status code tells the client whether to retry, re-authenticate or give up. Consider which downstream failures are the client's problem and which are the server's. ``` #### What This Part Should Cover - A classification of per-call outcomes: success, error status, timeout, connection failure - A justified mapping from combinations of outcomes to one overall status code, including partial failure - Per-section status in the body so the client can render whatever succeeded - Timeouts that bound the latency of the whole request ### What a Strong Answer Covers - A clean separation between calling services, classifying their results and building the HTTP response - Deterministic behavior when several services fail in different ways at once - No thread or connection leaks when a downstream call hangs - Tests for all-success, optional failure, required failure, timeout and mixed failures ### Follow-up Questions - A required service starts timing out on every request. How do you stop the bootstrap endpoint from tying up threads waiting on it (for example, with a circuit breaker), and what does the client see meanwhile? - One downstream service returns 429 Too Many Requests. What should the bootstrap response be, and should it carry a Retry-After header? - Which parts of the bootstrap payload could be cached, and which are safe to cache globally rather than per user? - The app team wants to add a new section every few weeks. How do you make adding a downstream service a configuration change rather than a code change?

Overview: Implement a bootstrap service that calls several independent downstream services concurrently, aggregates their data into one response for a client app, and returns an HTTP status code that reflects partial or total failure. It tests concurrent calls, timeouts, per-section error reporting, and mapping downstream failures to client-facing status codes.

|Home/Software Engineering Fundamentals/DoorDash
DoorDash logo
DoorDash
Sep 7, 2026
mediumSoftware EngineerOnsiteSoftware Engineering Fundamentals
0
0

A client app makes a single "bootstrap" request, typically when it starts, and expects one response containing everything it needs to render its first screen. That data lives in several independent downstream services, so the backend needs a BootstrapService that calls those services, aggregates their data into one response body, and returns that body with an HTTP status code.

Assume each downstream service is reached through a client that returns a response with an HTTP status code and a JSON body, or raises an exception when the call cannot complete (for example, a connection error). As an illustration, the bootstrap payload might combine a user-profile service, an app-configuration service and a promotions service.

Constraints and Clarifications

  • The downstream services are independent: no call needs another call's result.
  • A downstream call can succeed, return an error status (4xx or 5xx), be slow, or fail at the connection level.
  • The caller of the bootstrap endpoint sees only the one aggregated response: its status code and its body.

Clarifying Questions Guidance

  • Are some services required for the app to work at all, while others are optional sections that may be missing?
  • If an optional service fails, should the overall response still succeed, and how should the body tell the client which sections are missing?
  • When a required service fails, should a caller-caused error from that service (such as an authentication failure) be passed through, and which code should represent a downstream outage or timeout?
  • Is there a latency budget for the whole bootstrap call, and should each downstream service have its own timeout?
  • Should failed downstream calls be retried within the same request?
  • Does the client need per-section status information, or only an overall status code?

Part 1 — Aggregate the downstream data

Implement BootstrapService with a method that, given the requesting user's ID, calls every downstream service and returns one response whose body contains each service's data under its own key. For this part, assume every downstream call succeeds.

What This Part Should Cover Guidance

  • A clear interface for a downstream service and for the aggregated response
  • Concurrent downstream calls, with the resulting end-to-end latency analyzed
  • A response format that new services can join without changing its structure

Part 2 — Add HTTP response status handling

Now downstream calls can fail. Extend the service so that the aggregated response carries an HTTP status code that accurately reflects what happened, and so that the body tells the client what happened to each section. Explain which status code you return in each situation, and why.

What This Part Should Cover Guidance

  • A classification of per-call outcomes: success, error status, timeout, connection failure
  • A justified mapping from combinations of outcomes to one overall status code, including partial failure
  • Per-section status in the body so the client can render whatever succeeded
  • Timeouts that bound the latency of the whole request

What a Strong Answer Covers Guidance

  • A clean separation between calling services, classifying their results and building the HTTP response
  • Deterministic behavior when several services fail in different ways at once
  • No thread or connection leaks when a downstream call hangs
  • Tests for all-success, optional failure, required failure, timeout and mixed failures

Follow-up Questions Guidance

  • A required service starts timing out on every request. How do you stop the bootstrap endpoint from tying up threads waiting on it (for example, with a circuit breaker), and what does the client see meanwhile?
  • One downstream service returns 429 Too Many Requests. What should the bootstrap response be, and should it carry a Retry-After header?
  • Which parts of the bootstrap payload could be cached, and which are safe to cache globally rather than per user?
  • The app team wants to add a new section every few weeks. How do you make adding a downstream service a configuration change rather than a code change?
Loading comments...