Prompt
What are Backend for Frontend best practices?
Latest observation
Here's a rundown of Backend for Frontend (BFF) best practices:
Ownership and scope
- One BFF per client type (web, mobile, partner API), not one shared BFF trying to serve everyone — that defeats the purpose and just recreates a generic API with extra steps.
- The team that owns the client should own its BFF — this avoids the classic bottleneck where a mobile team has to wait on a separate backend team to change a response shape.
- Keep the BFF thin — it should orchestrate and reshape data, not own business logic or data. Business rules belong in the underlying services; the BFF's job is aggregation and presentation.
Design and data shaping
- Design each BFF's responses around exactly what that client's screens need — denormalized, pre-joined, and trimmed to avoid the client doing extra work or making follow-up calls.
- Avoid replicating REST purism inside the BFF — it's fine (even ideal) for a BFF endpoint to be tailored to one specific screen or flow rather than being a generic resource.
- Don't let the BFF become a dumping ground for every possible field "just in case" — this reintroduces the bloat problem BFFs exist to solve.
Avoiding duplication across BFFs
- If multiple BFFs need the same aggregation logic (e.g., "get user profile + recent orders"), extract that into a shared internal library or a shared orchestration service — don't let each BFF reimplement it slightly differently. Establish shared conventions (error format, auth handling, logging) across all BFFs even though each is owned by a different team, so debugging and onboarding don't require learning a new pattern per BFF.
Performance
-
Batch and parallelize calls to downstream services wherever possible — the BFF's value is largely in doing this coordination once so the client doesn't have to make multiple round-trips. Cache aggressively at the BFF layer for data that doesn't change often, especially for expensive multi-service aggregations.
-
Set timeouts and fallback behavior for each downstream call — if one service is slow or down, decide whether the BFF returns partial data or fails the whole request, and make that decision explicit rather than accidental.
Security
Authenticate at the BFF (or the gateway in front of it), not redundantly in every downstream service call that the BFF makes on the user's behalf.
- The BFF is a good place to enforce client-specific authorization rules — e.g., the mobile BFF might expose a narrower slice of data than the admin web BFF, even if both ultimately call the same backend services.
- Don't expose internal service details (internal IDs, service names, stack traces) through the BFF — treat it as a security boundary, not just a convenience layer.
Versioning and change management
- Version the BFF independently from the underlying services — a mobile app on an old version shouldn't break just because a backend service changed, as long as the BFF contract stays stable.
- Because a BFF is tightly coupled to its one client, breaking changes are more contained than changing a shared general-purpose API — but still communicate changes clearly to the client team, especially for mobile where release cycles are slower.
Observability
- Trace requests end-to-end from BFF through to each downstream service call — since the BFF fans out to multiple services, debugging a slow or failed response requires visibility into which specific downstream call was the bottleneck. Monitor the BFF's own latency separately from the services it calls, so you can tell whether a slowdown is aggregation overhead or a downstream service issue.
When to introduce a BFF (and when not to)
- Introduce a BFF when different client types have meaningfully different data or interaction needs — if all your clients want the same shape of data, a BFF adds complexity without benefit; a shared API or a general gateway may be enough.
- Don't over-fragment — a BFF per client type is common, but a BFF per screen or per feature is usually excessive and creates maintenance sprawl.
- Watch for a BFF quietly accumulating business logic over time — if it starts making decisions rather than just aggregating and shaping data, that logic likely belongs in a proper service instead.
Practical baseline
One BFF per distinct client type, owned by that client's team.
BFF aggregates and reshapes; underlying services own business logic and data.
Auth enforced at the BFF/gateway layer, not duplicated per downstream call.
Shared conventions (errors, logging, auth patterns) across all BFFs even though ownership is distributed.
Full tracing from BFF through downstream calls for debugging.
Periodic review to catch business logic creeping into the BFF, and to catch duplicated aggregation logic across BFFs that should be shared instead.
Observation history
See 1 earlier observation
Create a free Obsurfable account to unlock historical responses, model comparisons, and deeper brand intelligence.
How did Obsurfable measure this prompt?
Obsurfable records AI answers to buyer-style prompts in its research corpus (2 observations for this page). Metrics are distributions over observations, not a single static ranking.
Which AI systems does Obsurfable collect answers from?
OpenAI, ChatGPT, Google, Gemini, Google AI Mode, Anthropic, Claude, Perplexity, Grok, DeepSeek, Mistral, Copilot, and Meta AI.