Skip to content

// Communication & Integration · 08

Backend for Frontend

Mobile / Webleads toOwn BFFleads toServices

Each client gets its own backend, shaped for its screens.

How it fits together

Backend for Frontend structure«client»Mobile appMobile BFFGET /hometrims to screen fieldsProfileOrders«client»Web appWeb BFFGET /dashboardfull payloadsRecommendations1 GET /home1 GET /dashboard2 parallel
uses / calls· numbered steps replay in order
  • Mobile app uses / calls Mobile BFF (1 GET /home)
  • Web app uses / calls Web BFF (1 GET /dashboard)
  • Mobile BFF uses / calls Profile (2 parallel)
  • Mobile BFF uses / calls Orders
  • Mobile BFF uses / calls Recommendations
  • Web BFF uses / calls Profile
  • Web BFF uses / calls Orders

Spot it

  • Mobile downloads web-sized payloads
  • The app makes many calls to render one screen
  • Web and mobile teams fight over one API

It costs

More deployables, and logic can get duplicated across BFFs.

In code

public sealed class HomeScreen(IProfileClient profile, IOrdersClient orders, IRecsClient recs){    public async Task<HomeView> GetAsync(string userId, CancellationToken ct)    {        var profileCall = CallAsync(token => profile.GetAsync(userId, token), ct);        var ordersCall = CallAsync(token => orders.RecentAsync(userId, token), ct);        var recsCall = CallAsync(token => recs.ForAsync(userId, token), ct);​        await Task.WhenAll(profileCall, ordersCall, recsCall);        return new HomeView(profileCall.Result, ordersCall.Result ?? [], recsCall.Result ?? []);    }​    private static async Task<T?> CallAsync<T>(        Func<CancellationToken, Task<T>> call,        CancellationToken ct)    {        using var timeout = CancellationTokenSource.CreateLinkedTokenSource(ct);        timeout.CancelAfter(TimeSpan.FromSeconds(1));        try        {            return await call(timeout.Token);        }        catch (Exception) when (!ct.IsCancellationRequested)        {            return default;        }    }}
Go deeperThe full explanation and what to ask for · 1 min readExpand

A backend for frontend is a thin server-side layer dedicated to one client experience: the iOS app, the web app, a partner integration. It aggregates calls to downstream services, trims and reshapes the response, and adapts auth to what that client can safely hold.

The classic mistake is letting business rules creep in. When two BFFs both calculate prices, they will eventually disagree. Keep domain logic in the services and let the BFF do composition and presentation. Ideally the team that builds the frontend owns its BFF.

For browser apps, a BFF can keep OAuth tokens server-side and give the browser only a secure cookie. It sits behind or alongside the API gateway, and often uses GraphQL or parallel REST calls to compose its responses.

Ask for it

  • aggregation
  • client-specific API
  • response shaping
  • token handler
  • graceful degradation

Create a mobile BFF owned by the mobile team: GET /home calls Profile, Orders and Recommendations in parallel with a 1s timeout each, returns only what the screen shows, and degrades to empty sections on failure. Route all other paths unchanged to the services.