Practice this topic in a realistic system design interview
An API gateway gives every client one controlled entry point. But a single entry point still means a single API, and different clients often need very different things from it.
The Backend for Frontend (BFF) pattern gives each type of client its own backend layer. Each BFF exposes an API designed for one client experience, while the services behind it stay the same.
This chapter covers what the Backend for Frontend pattern is, why systems with different types of clients use it, how it differs from a regular API gateway, and the trade-offs that come with giving each frontend its own backend.
Suppose we're building a video streaming application. It has a web app, an iOS app, an Android app, and a smart TV app. Behind them, we have several microservices, including a user service, catalog service, recommendation service, and watch history service.
To keep things simple, we expose one general-purpose API that every client uses.
At first, this works well. But over time, the clients start needing very different things.
| Client | Environment | What It Needs |
|---|---|---|
| Web app | Large screen, usually a fast connection | Rich pages with lots of detail |
| Mobile app | Small screen, often a slower network | Smaller responses and fewer network requests |
| TV app | Large screen, controlled with a remote | Large thumbnails and its own layout and navigation |
Now one API has to satisfy several very different user experiences.
Two problems usually appear first.
Suppose the movie details endpoint returns the full cast, reviews, and technical metadata because the web app uses all of it. The mobile app may only need the title, poster, and rating. But it still downloads the entire response over a mobile connection.
To render its home screen, the mobile app might need data from the user service, recommendation service, and watch history service. If the client has to call each one separately, that means several network round trips before the screen can load.
There is also an organizational problem. Every client team depends on the same backend team to change the shared API. The mobile team asks for a smaller response. The web team asks for more fields. Every change has to be checked against all the other clients to make sure nothing breaks.
Release schedules make this harder, because clients ship at very different speeds.
| Client | Typical Release Constraint |
|---|---|
| Web app | Can deploy many times per day |
| iOS app | App Store review, and users upgrade slowly |
| Android app | Often faster than iOS, but still tied to app versions |
| TV app | Platform review and very slow upgrade cycles on older devices |
A shared API has to keep working for the oldest version of the slowest client. Over time, the shared API becomes a bottleneck for both the clients and the teams building them.