Standalone conceptPatternChapter II · Communication · Building block 23 of 23

API composition

API composition joins separate data sources in the read path.

  1. ComposerDecomposes the request and joins responses without taking ownership.
  2. Time budgetLimits fan-out and determines abort or partial result.
  3. FreshnessShows the point in time represented by each combined field.

Context

Why this is important

It preserves data ownership but makes latency and partial failures properties of every query.

The example starts as internal module composition. Distributed calls are hypothetical; seven modules and one shared database remain current.

Shop example · Mapping

Query strategies for the order view

The current shop has seven modules in a modular monolith and one shared database. Customer service needs an order view from Order, Payment, and Shipping. An internal composer calls the three module APIs in parallel, limits each subrequest, and marks a missing shipping status as temporarily unknown. Network failures arise only in a hypothetical later service split; p95 latency, fan-out, and partial-result measurements then determine whether a materialized read model is preferable.

This is how you read the picture

  1. Composer Map response fields to owners
  2. Time budget Parallel subcalls with deadlines
  3. Freshness Expose freshness per field
Query strategies for the order view
ComparisonStrategyStrengthCost
API compositionSources remain authoritativeCurrent data when calls succeedFan-out and partial failures per request
Materialized read modelOne fast queryExplicitly observable projectionLag, rebuild, and correction
Client compositionClient controls presentationLess server logicMany round trips and duplicated failure logic
Runtime cost, freshness, and maintenance shift with each strategy.

Benefits & limitations

Helps if:

  • A few sources and manageable queries need data at request time.
  • Partial results can be represented clearly as unknown or stale.
  • A transitional solution should preserve separate ownership before a projection is justified.

Boundaries

  • The slowest source and retries determine the total response and can multiply load.
  • Multi-stage joins and large result sets make runtime composition expensive and unpredictable.
  • The composer must not become a second source of business truth or a hidden write interface.

In practice

  1. Compose the order overview from order status and shipping status. Record each query owner, time budget, and behavior when a result is missing.
  2. Delay the shipping call and measure total response latency. Decide whether partial results can be shown or the view must fail as a whole.
  3. Compare runtime composition with a maintained read model for frequent queries. Include freshness, operational dependencies, and change effort in the choice.
Read the detailed explanation

A composer decomposes a query, calls the owners of required data in parallel or dependency order, and joins responses through stable keys. It owns the combined representation while business rules and writes remain with the sources.

Every runtime call consumes latency and adds a failure path. The response contract must therefore define deadlines, missing partial responses, caching, and visible freshness per field.

CQRS can provide a prepared read model when fan-out or latency argues against runtime composition. API Contracts protect the shape and meaning of source responses.

Check your understanding

Test yourself in three stages

  1. ReadingCheck in the picture

    Who owns the combined business data?

    View the solution with justification

    The source modules; the composer owns only the response representation.

  2. ApplyingTransferred to a new situation

    How does the order view handle missing shipping status?

    View the solution with justification

    It returns available data and marks Shipping as unknown within the budget.

  3. EvaluateWeighing an alternative

    When is a read model preferable?

    View the solution with justification

    With high fan-out, strict latency, or recurring complex joins.

Continue on the learning path

With that, you have Communication & APIs run through. It continues with Distributed systems.