Skip to main content

API Gateway & Backend-for-Frontend

Level 4: Level 4: Scaling Compute & Trafficmedium30 mingatewaybff

A thin, horizontally scaled gateway owns north-south cross-cutting concerns, BFFs shape payloads per client type, the mesh owns east-west, and business logic stays in services.

Where the cross-cutting concerns live

As a monolith splits into dozens of microservices, a hard question appears: where do the cross-cutting concerns live? Every client call needs authentication, TLS, rate limiting, routing, and observability. You do not want thirty services reimplementing all of that, and you do not want each client talking directly to thirty services. The API gateway is the single north-south entry point that owns those concerns so the services behind it stay thin.

A gateway centralizes: TLS termination, authentication and authorization, rate limiting and quotas, routing, request/response transformation, response aggregation, API versioning and canary routing, and observability. Concrete implementations: Kong, AWS API Gateway, Envoy-based gateways, Apigee, or a Netflix Zuul-style edge service.

Check yourself
The order service needs to call the inventory service inside the cluster. Should that call route through the API gateway, which already owns auth, rate limiting, and observability?

Draw the boundary carefully. The gateway handles north-south traffic (client to system). Service-to-service east-west traffic is the job of a service mesh (Istio, Linkerd, Envoy sidecars), which handles mTLS, retries, and load balancing between services. Routing internal calls through the public gateway is a common design error. Business logic belongs inside services, not in either the gateway or the mesh.

Check yourself

Sort each concern into the layer that should own it.

TLS termination and rate limiting for client traffic
mTLS and retries between internal services
The discount calculation for checkout
Canary routing of client requests to a new API version
Load balancing calls from the order service to inventory
Deciding whether a refund is allowed

Backend-for-frontend (BFF)

One generic API rarely fits every client. A mobile app on a slow network wants a small, denormalized payload in one round trip; a web SPA wants richer data; a partner API needs stable, versioned contracts. A single endpoint serving all three leads to over-fetching (mobile downloads fields it never renders) or under-fetching (five calls to build one screen). A BFF is a thin gateway per client type: bff-mobile, bff-web, bff-partner. Each aggregates and shapes exactly what its client needs and is owned by that client's team, so a mobile change does not ripple through the web contract. GraphQL is one way to give clients field-level selection and reduce the need for many hand-written BFFs, at the cost of its own query-cost and caching complexity.

BFFs, the gateway, and the north-south / east-west boundary
Step 1 / 4

Stage 1 of 4: Three client types need different payloads: mobile wants a small denormalized response in one round trip, the web SPA wants richer data, and the partner needs stable versioned contracts. One generic endpoint over-fetches or under-fetches.

North-south traffic enters through a per-client BFF and the gateway; east-west traffic between services belongs to the mesh, and domain rules stay in the services.

The two big risks

First, the gateway is a single point of failure and a latency tax: every request pays one extra hop, and if it is down the whole product is down. So it must be horizontally scaled, stateless, health-checked, and kept fast (offload heavy work, cache authz decisions and hot responses). Second, and worse, the gateway can rot into a god-object: teams keep adding "just one more" piece of business logic until the edge holds orchestration and domain rules that belong in services. Then every service change requires a gateway change, deploys serialize on one component, and you have rebuilt the distributed monolith you split up to avoid.

Interview nuance: the strongest answers name what does not belong at the gateway (domain business rules, per-feature orchestration, data ownership) as crisply as what does. Pre-empt the god-object probe by stating a rule: the gateway does cross-cutting concerns and routing only, business logic lives in the owning service.

Recap: put auth, TLS, rate limiting, routing, and observability at a horizontally scaled gateway for north-south traffic, use a BFF per client type to avoid over/under-fetching, leave service-to-service concerns to the mesh, and hold the line against business logic creeping into the edge.

Check yourself
A teammate proposes putting the coupon-validation rules in the gateway, since every checkout request already passes through it. If you say yes, what does the system look like six months later?

Apply

Your turn

The task this lesson builds to.

Design an API gateway layer for a microservices product with web, mobile, and partner API clients.

Think about

  1. What belongs at the gateway vs inside services vs the mesh?
  2. When is a BFF the right pattern?
  3. How do you keep the gateway from becoming a god-object?

Practice

Make it stick

A second problem on the same idea, so it survives past today.

Design the API gateway and BFF layer for Netflix-scale streaming, where a single home-screen load fans out to dozens of microservices (recommendations, artwork, continue-watching, billing status) and the same backend must serve TVs, phones, browsers, and game consoles with wildly different capabilities. Lead with the request topology.

Think about

  1. Why does one generic API fail across TVs, phones, and consoles?
  2. At a dozens-of-services fan-out, what must happen when one non-critical service is slow?
  3. Which fields fail differently from cosmetic ones?