Implementing API Composition Patterns

1. Using Backend for Frontend (BFF) Pattern

Web App  → Web BFF   ┐
Mobile   → Mobile BFF├→  [microservices]
Smart TV → TV BFF   ┘
      
BFF TypeOptimizes For
WebSEO data, larger payloads
MobileSmaller responses, fewer calls
TV/IoTSlow CPU, simple JSON
PartnerStable contract, masked fields

2. Implementing API Orchestration

StepAction
1Receive client request
2Decompose into N service calls
3Execute with retries/timeouts
4Compose response shape
5Return unified result

3. Using API Facade Pattern

AspectDetail
Single interfaceHide N implementations
DecouplingClients don't change with backends
AggregationCombine multiple calls
TranslationAdapt legacy formats

4. Implementing Aggregator Pattern

Example: Aggregator pseudocode

// Fan-out, fan-in
List<CompletableFuture<Item>> futures = backends.stream()
  .map(b -> CompletableFuture.supplyAsync(() -> b.fetch(id)))
  .collect(toList());

List<Item> items = futures.stream()
  .map(f -> f.completeOnTimeout(null, 2, SECONDS).join())
  .filter(Objects::nonNull)
  .collect(toList());

5. Configuring Micro-Gateway Pattern

PropertyValue
Footprint< 50 MB RAM
DeploymentPer-service or sidecar
ExamplesEnvoy, Traefik, Tyk MDCB
Use caseEdge + service mesh hybrid

6. Setting Up Scatter-Gather Pattern

Request → [scatter] → svc-A, svc-B, svc-C (parallel)
                  ←──── responses
        → [gather] → merge → reply
      

7. Configuring Chain Pattern

StepAction
1Call A → response A
2Use A.id → call B
3Use B.token → call C
LatencySum of all steps

8. Using Branch Pattern

Example: Conditional branch

if (req.type == OrderType.PHYSICAL) {
  return shippingService.create(req);
} else if (req.type == OrderType.DIGITAL) {
  return licenseService.issue(req);
} else {
  return subscriptionService.start(req);
}

9. Implementing Splitter Pattern

InputOutput
Bulk arrayN parallel single requests
Large payloadMultiple chunks to different svcs
Multi-actionFan out to handlers

10. Setting Up Content-Based Router

Example: Body-field router

local body = cjson.decode(kong.request.get_raw_body() or "{}")
local target
if body.event_type == "payment" then       target = "payment-svc"
elseif body.event_type == "refund" then    target = "refund-svc"
elseif body.event_type == "chargeback" then target = "dispute-svc"
end
kong.service.set_target(target, 8080)