Microservices Patterns/API Gateway & BFF

BFF & Aggregation Patterns

Backends for Frontends per client surface, parallel fan-out, feed and notification fan-out on read vs write, cached timelines, and GraphQL gateway as BFF.

3/5Overview: 35m

BFF pattern

Backend-for-Frontend — one backend per client experience (mobile, web, partner), shaping responses for that UI's needs.

Not a new domain service — a thin orchestration layer over core microservices.

Why not one API for all clients?

ClientNeeds
MobileSmall payloads, batch endpoints, offline-tolerant
Web SPARich graphs, fewer round-trips
PartnerStrict SLA, API keys, webhooks

Single generic API → over-fetching, versioning conflicts, release coupling.

BFF responsibilities

  • Aggregate multiple downstream calls
  • Translate errors to client-friendly shapes
  • Client-specific auth (mobile device attestation)
  • Owns GraphQL schema or REST surface for that client

Must not own core business rules — checkout pricing stays in Order/Pricing services.

Aggregation patterns

Parallel fan-out:

Promise.all([getUser(), getOrders(), getRecommendations()])

Watch tail latency — p99 = max(subcall p99), not sum.

Cached denormalized reads — Redis materialized view for home feed; invalidate on events.

GraphQL gateway — federated subgraphs; BFF team owns supergraph composition (Communication → GraphQL).

Feed, timeline & notification fan-out

High-follower read paths are the classic Staff deep dive — storage layout is in Databases → Search; aggregation lives here.

Fan-out on read vs fan-out on write

ApproachWrite costRead costFreshnessPick when
Fan-out on readO(1) per postO(followers) or cached mergePull model; cache helpsMost users have modest follower counts
Fan-out on writeO(followers) per postO(1) per home timeline readPush precomputed timelinesRead-heavy timelines, celebrity problem handled separately
HybridNormal users: write fan-out; celebrities: read mergeMixedIndustry default (Twitter-style)Large social products at scale

Celebrity problem: one user with 100M followers — never fan-out on write to all timelines. Use a celebrity bucket: merge celebrity posts at read time from a hot cache or dedicated shard.

BFF role in feed assembly

GET /home-feed → BFF loads timeline IDs (precomputed or cache) → parallel fetch post bodies + authors (batch APIs) → optional ranking service for "For You" → merge, truncate payload for mobile

Materialized feed cache in Redis (feed:userId → list of post IDs) — invalidate or append on new post event. Cross-reference Databases → Application Caching for stampede and invalidation.

Notifications

Fan-out on write is common: event → queue → per-device delivery workers. Idempotent consumers (Communication → idempotency). Rate-limit per user to prevent notification storms.

Timed case practice → System Design Use Cases (news feed, notification system).

Anti-patterns

  • Mega-BFF — one team gatekeeping all product APIs
  • BFF calling BFF — layers of aggregation
  • Business logic creep — discount rules in BFF because "it's easier"

BFF vs API gateway

GatewayBFF
AudienceOften all external trafficSpecific client type
LogicPolicy, routingAggregation, shaping
Count1–2 per environment1 per client surface

Can combine: mobile BFF behind same gateway with path routing /mobile/*.

Staff interview

"Where does the BFF live in deploy topology?" — same cluster as edge, autoscales with client traffic, stateless, no private data store (cache only).

Further Reading

Hands-On Tasks (Optional)

Architecture drills and whiteboard exercises. Assumes Communication & Data Transfer and Distributed Systems fundamentals.

  • Design BFF split for mobile vs web

    Same product, different payloads: mobile needs minimal fields + push tokens; web needs rich admin. One BFF or two? What stays in domain services?

    15m