Backend-for-Frontend Pattern for Web and Mobile
Why I use BFF
A mobile application and desktop web application can use the same business capabilities but need different payloads.
Without BFF:
mobile -> 8 microservice calls
web -> 12 microservice callsThe browser becomes the integration layer.
A BFF can provide:
Mobile -> Mobile BFF --\
-> Domain Services
Web -> Web BFF -----/NestJS composition
@Get('/home')
async home(
@Req() request: AuthenticatedRequest,
) {
const userId = request.user.id;
const [
profile,
upcomingBookings,
offers,
] = await Promise.all([
this.customer.profile(userId),
this.booking.upcoming(userId),
this.offers.forUser(userId),
]);
return {
profile: {
name: profile.displayName,
},
bookings:
mapMobileBookings(
upcomingBookings,
),
offers:
offers.slice(0, 5),
};
}The BFF shapes data.
It should not decide:
whether booking can be cancelled
how refund is calculated
whether supplier can bidThose are domain rules.
Next.js as BFF
For a Next.js site, server-side routes/actions can perform BFF responsibilities:
export async function GET() {
const [profile, articles] =
await Promise.all([
api.get('/profile/me'),
api.get('/articles/latest'),
]);
return Response.json({
profile: profile.data,
articles: articles.data,
});
}I still separate that composition from reusable backend domain services.
Authentication
The BFF can hold a secure server-side session/token and call internal APIs.
This can reduce sensitive token exposure in browser JavaScript.
But authorization still belongs downstream.
Caching
BFF caching is useful for:
navigation metadata
public reference data
CMS contentI avoid caching per-user sensitive responses unless keys and invalidation are very carefully scoped.
Failure scenarios
One downstream call fails
Define partial response or fail complete request depending on user journey.
Fan-out becomes large
Move expensive aggregates to a read model.
BFF duplicates business rules
Refactor those rules back into owning services.
Web and mobile BFFs diverge excessively
Share contracts/utilities where useful without forcing the clients to return identical shapes.
Production checklist
- Keep domain rules out.
- Bound dependency timeouts.
- Trace fan-out.
- Avoid N+1.
- Cache only intentionally.
- Protect server-side credentials.
- Keep response client-focused.
- Monitor BFF latency and downstream contribution.
- Move complex aggregates to projections.
FAQ
BFF vs API Gateway?
Gateway owns traffic policy; BFF owns client-specific composition.
One BFF per screen?
No.
Can Next.js be a BFF?
Yes, especially for web-specific server composition.
Related architecture guides
- [Microservices Design Patterns I Have Used in Real Enterprise Projects](/articles/microservices-design-patterns-real-enterprise-projects)
- [API Gateway Pattern](/articles/api-gateway-pattern-kong-aws-azure-spring-nestjs)
-
Architect's final take
A BFF is valuable when it protects the client from backend topology without stealing business ownership from domain services.
Your feedback helps prioritize deeper technical content.






