Go architectures · 3 MIN READ

BFF: an API shaped for one client

Compose client-specific views while retaining business ownership.

Compose client-specific views while retaining business ownership. A backend for frontend provides an API suited to a particular client, such as mobile. Trace the worked Go example, then compare the benefit with the cost before applying this design to your own project.

Architecture · A MAP OF THE IDEA

  1. Mobile requests a home view
  2. BFF composes safe client fields
  3. Domain services retain business rules

Useful when

  • Mobile and desktop have different data needs
  • Aggregation avoids many client round trips

Watch out

  • Adds a deployed component and timeout budget
  • Duplicated business rules can diverge

Implementation & operation cost: High

Fit depends on the task

Small tool or CLI1/5
Domain-rich application3/5
Independent distributed services4/5

Editorial suitability, not benchmarks or a universal ranking. Styles describe different axes and can be combined.

01

The design decision

A backend for frontend provides an API suited to a particular client, such as mobile. It can combine downstream responses and remove fields the client does not need. Authorization and business invariants still belong at trustworthy service boundaries, not only in the BFF.

02

A complete Go example

Read this program from the entry point and follow the calls shown in the diagram. The output is included at the end so you can check the behavior without a compiler.

go
package main

import (
	"fmt"
)

type Profile struct{ Name, InternalNote string }
type MobileHome struct {
	Greeting string
	Unread   int
}

func Home(p Profile, unread int) MobileHome {
	return MobileHome{Greeting: "Hello, " + p.Name, Unread: unread}
}

func main() {
	view := Home(Profile{Name: "Ada", InternalNote: "private"}, 3)
	fmt.Println(view.Greeting, view.Unread)
}

// Output:
// Hello, Ada 3
Read the code

Home maps a rich internal object to the client view without copying InternalNote. In a real BFF, downstream calls can fail independently; define timeout budgets and whether partial data is acceptable before parallelizing aggregation.

03

Tradeoffs and the simpler alternative

One extra boundary helps clients with genuinely different data and release needs. If all clients need the same API, a shared endpoint may be simpler. Do not duplicate pricing or authorization policy in every BFF; client shaping is its main reason to change.

04

Aggregate for one client without moving domain ownership

A backend for frontend adapts several capabilities to the screens of a specific client. It can reduce round trips, tailor pagination and hide service topology. Keep pricing, payment and authorization invariants in the owning service; a BFF should not become a second business system with conflicting rules. A mobile BFF and a web BFF can differ in response shape while using the same underlying contracts.

05

Handle fan-out without multiplying latency

Call independent services concurrently under a total deadline, cap concurrency and decide which results are essential. A profile panel might allow a missing optional recommendation, while a checkout must fail if price validation is unavailable. Preserve the distinction in the response instead of returning an empty success object for every dependency failure. Cache only with a key that includes required user and permission scope; shared caching of personalized responses can leak data.

06

Test screen contracts and graceful degradation

Use fixtures for complete results, one optional dependency timeout and one essential dependency failure. Verify authorization on the aggregate response and prevent internal service errors from exposing private topology. Track fan-out count and deadline exhaustion. Introduce a BFF when distinct clients actually need different composition; one frontend calling one simple API rarely needs another deployable intermediary.

TAKE THIS WITH YOU

Shapes an API around one client’s needs. One extra boundary helps clients with genuinely different data and release needs. If all clients need the same API, a shared endpoint may be simpler. Do not duplicate pricing or authorization policy in every BFF; client shaping is its main reason to change.

Check your understanding

Which statement best describes BFF: an API shaped for one client?

Go to the source

Progress stays in this browser. No account needed.