Lesson 23 / 26
Backend for Frontend and Aggregation
Shape APIs per client type and combine several backend calls into one.
One screen, one call
A mobile home screen may need data from five services; calling each over a slow network is wasteful. The Backend for Frontend (BFF) pattern puts a small purpose-built API in front of the services for each client type (mobile, web, partner). It aggregates calls (in parallel), trims fields and adapts formats so each client makes one call and downloads only what it needs. A gateway can do light aggregation; heavier orchestration belongs in a dedicated BFF service owned by the front-end team. Watch for tight coupling, partial failures (return what you have, flag what is missing) and duplicated logic across BFFs.
Shape the API and release safely
Patterns such as backend-for-frontend and shadowing help clients and releases.
A BFF endpoint (illustrative)
Calls run in parallel and a failing optional dependency degrades gracefully instead of failing the whole screen. get_* stand for your service clients.
import asyncio
async def home_screen(user_id):
profile, orders, recs = await asyncio.gather(
get_profile(user_id),
get_recent_orders(user_id, limit=3),
get_recommendations(user_id),
return_exceptions=True,
)
return {
"profile": profile, # required
"recent_orders": orders if not isinstance(orders, Exception) else [],
"recommendations": recs if not isinstance(recs, Exception) else [],
"degraded": [n for n, v in (("orders", orders), ("recommendations", recs)) if isinstance(v, Exception)],
}Quick check: What is the aim of the BFF pattern?
- Give each client type an API shaped to its needs, with fewer round trips
- Replace all microservices
- Remove the gateway
- Encrypt databases
Answer
Give each client type an API shaped to its needs, with fewer round trips — A tailored aggregation layer reduces chattiness and client complexity.