BFF (Backend for Frontend) and Mobile Backend
A thin backend layer for each client (Android, iOS, web, TV) that stitches microservice data together according to what that screen needs.
59.1 Why is it used?
- If a mobile app calls 8 different microservices for one screen, the page opens very late on a slow network (3G/4G).
- Web needs big detailed data, mobile needs a small payload with fewer fields, and a TV app needs a different layout. One generic API does not fit all.
- Mobile apps keep running on old versions (people do not update). The backend has to support many app versions.
- Offline mode, push notifications, forced app updates and slow-network handling are special needs of mobile.
- If the frontend team owns its own BFF, there is less dependency on backend teams and releases are faster.
59.2 How it works
- 1.Mobile app (Android / iOS, Jio 4G): GET /mobile-bff/home, just 1 call
- 2.API Gateway (Kong / AWS API GW): auth, rate limit, /v1 /v2 versioning
- 3.mobile-bff (Node.js / GraphQL): small JSON, no business logic, only aggregate + shape
- 4.Parallel calls, 200 ms timeout: User service, Location, Offers, Recommendations, Cart count
- 5.If Recommendations is slow, fall back to 'popular items'; the page does not fail
For the web browser there is a separate web-bff: a big grid and SEO details
- BFF pattern: client -> its BFF (mobile-bff, web-bff) -> internal microservices. The BFF aggregates, filters and formats.
- Aggregation: for the home screen, call user, cart, offers and recommendations in parallel and build one response. 1 round trip.
- GraphQL BFF: the client says which fields it wants. Over-fetching/under-fetching goes away, and one endpoint serves many services.
- API versioning: /v1, /v2 or a header; keep the old contract alive for old app versions until usage drops.
- Force update: call /config at app startup -> min_supported_version. If the app is older than that, show an 'Update required' screen; for a soft update show an optional prompt.
- Offline sync: the app keeps data in a local DB (SQLite/Room/Core Data), queues changes, and syncs when the network returns; conflict resolution (last-write-wins or merge).
- Mobile optimisations: compress the payload (gzip/brotli), pagination, per-device image resizing, HTTP/2, cache headers, ETag.
- Server-driven UI: the backend says which widgets appear on the screen and in what order. You can change the home page without an app release.
- 1.App v3.2 starts -> GET /config (min_supported_version = 4.0 + feature flags, Remote Config)
- 2.3.2 < 4.0 -> 'Update required' screen
- 3.Older but OK version -> soft update prompt
- 4.Old app versions live on for weeks/months, so keep the /v1 contract alive until then
- 1.Local cache (SQLite / Room / Core Data): show the last home screen instantly
- 2.Network is back -> background sync
- 3.Send the queued changes, last-write-wins or merge
- 4.Firebase / AppSync have offline sync + push (FCM) built in
In a GraphQL BFF the client asks for the fields itself, so over/under-fetching ends; add a depth limit
59.3 Tools you can use
| Tool | Type | How it is used |
|---|---|---|
| Apollo GraphQL / GraphQL Federation | GraphQL server/gateway | A single GraphQL BFF that joins many subgraphs (user, order, product); the client sends its own query. |
| Node.js (Express/NestJS) / Spring Boot | Custom BFF service | A small service per client that calls the internal APIs in parallel and shapes the response. |
| Firebase | Mobile backend-as-a-service (Google) | Auth, Firestore (offline sync built in), FCM push, Remote Config (force-update flag), Crashlytics. |
| AWS Amplify / AppSync | Managed mobile backend | AppSync = managed GraphQL with real-time subscriptions and offline sync; the Amplify SDK handles auth/storage. |
| Azure API Management / Kong / AWS API Gateway | API Gateway | In front of the BFF: auth, rate limit, versioning routes; some simple aggregation too. |
| Supabase | Open-source BaaS | Postgres + auth + storage + realtime; an open-source alternative to Firebase for small apps. |
59.4 Comparison: REST BFF vs GraphQL BFF vs Firebase (BaaS) vs Generic API Gateway
| Point | Custom REST BFF | GraphQL BFF | Firebase / BaaS | Generic API Gateway |
|---|---|---|---|---|
| What it is | A separate service per client | One schema, the client chooses fields | Ready-made backend services | A routing, auth, rate-limit layer |
| Payload control | The BFF fixes it per screen | Exact fields from the client query | Client talks to the DB/SDK directly | None, whatever the backend returns |
| Round trips | 1 per screen | Many resources in 1 query | Several SDK calls, offline cache | One per service |
| Caching | HTTP/CDN caching is easy | Hard (POST, single endpoint), needs persisted queries | SDK local cache | HTTP caching is easy |
| Complexity | Medium, you maintain a service per client | Schema design + the N+1 problem (DataLoader) | Low at first, vendor lock-in | Low |
| Scale/control | Full control | Full control | Managed by Google, cost grows with usage | Full control |
| Best for | Big teams, different needs per client | Many clients, flexible screens | Startup MVPs, chat, realtime apps | When no aggregation is needed |
59.5 When to choose which
- Custom REST BFF: when web and mobile needs differ a lot and each frontend team owns its BFF.
- GraphQL BFF: many clients, fast-changing screens, lots of resources on one screen.
- Firebase/Amplify: startup MVP, small team, you need realtime + offline + push quickly.
- API Gateway only: when the client has to call just one or two services and needs no aggregation.
- Do not put business logic in the BFF. It should stay in the core services; the BFF only aggregates and shapes.
59.6 Real-world example
Scenario: the home screen of a Flipkart/Swiggy type app.
- The app opens: first the /config call, with min_supported_version and feature flags. If the app version is old, show the force-update screen.
- Then one call: GET /mobile-bff/home. The mobile BFF calls the user, location, offers, recommendations and cart count services in parallel.
- Each call has a timeout (like 200 ms); if recommendations is slow, show the 'popular items' fallback and the whole page does not fail.
- The BFF builds a small JSON: only the fields shown on a mobile card, with image URLs for the device size.
- The web BFF returns a different response from the same services: a bigger grid, more details and SEO data.
- On a poor network the app instantly shows the previous home data from the local cache and refreshes in the background.
- Netflix and SoundCloud have written publicly about the BFF/API-per-device approach: a separate API layer for different devices.
59.7 Interview tips
- Putting business logic and DB access into the BFF: it becomes a new monolith and logic gets duplicated.
- A breaking API change without versioning: the app crashes for users on old versions; mobile users do not update for weeks/months.
- Not putting a query depth/complexity limit on GraphQL: one heavy query can take the backend down.
- Interview tip: start from the problem 'many calls on a slow mobile network' and then explain BFF + aggregation + force update + offline sync.