logo
Mastering API Patterns: BFF vs. Gateway vs. GraphQL (2026 Guide)

Jayesh Jain

Jan 30, 2026

4 min read

Share this article

Mastering API Patterns: BFF vs. Gateway vs. GraphQL (2026 Guide)

Introduction

In the early days of development, the frontend talked directly to the database (monoliths). Then came microservices, and suddenly our frontends had to make 15 HTTP requests just to render a "User Profile" page.

This introduced the "Chatty Interface" problem: high latency, over-fetching data, and complex frontend logic.

To solve this, architects developed several patterns to decouple the client from the server complexity. Today, we compare the titans: API Gateway, Backend for Frontend (BFF), and GraphQL.


1. The API Gateway Pattern

The API Gateway is a single entry point for all clients. It sits between the public internet and your internal microservices.

How it Works

The client sends a request to api.myapp.com/products. The Gateway routes this to product-service:8080, handles authentication, rate limiting, and caching, and returns the response.

  • Pros: Centralized security, simple for clients (one URL).
  • Cons: It becomes a "God Object." If the Mobile team needs a smaller payload but the Web team needs full details, the Gateway developer has to compromise, or the endpoint becomes bloated.

2. The Backend for Frontend (BFF) Pattern

The BFF pattern acknowledges that Mobile and Web clients have different needs.

  • Mobile: Needs small distinct payloads to save battery and data. Bandwidth is unreliable.
  • Web: Can handle larger payloads and more concurrent requests.
  • Public API: Needs strict versioning and docs.

Instead of one "General Purpose API," you build specific API layers for each interface.

How it Works

  • mobile-api.myapp.com -> Talks to internal Microservices -> Formats for iOS/Android.
  • web-api.myapp.com -> Talks to internal Microservices -> Formats for React Dashboard.

Code Example: Implementing a BFF in NestJS

Here is how a BFF aggregates data from multiple internal services to send a "clean" response to a Mobile App.

1// mobile-bff.controller.ts 2@Controller('mobile/dashboard') 3export class MobileDashboardController { 4 constructor( 5 private readonly userService: UserService, 6 private readonly orderService: OrderService, 7 private readonly notifService: NotificationService 8 ) {} 9 10 @Get() 11 async getDashboard(@Headers('user-id') userId: string) { 12 // 1. Parallelize downstream calls to microservices 13 const [user, orders, unreadCount] = await Promise.all([ 14 this.userService.findById(userId), // Returns { id, name, email, address, preferences... } 15 this.orderService.getLastOrder(userId), // Returns full order object 16 this.notifService.getUnreadCount(userId) 17 ]); 18 19 // 2. Transform and Filter (The BFF Logic) 20 // The mobile app ONLY needs the name and last order status. 21 // We strip out 90% of the data to save bandwidth. 22 return { 23 greeting: `Hello, ${user.firstName}`, 24 status_card: { 25 last_order_id: orders.id, 26 status: orders.status, // e.g., "Shipped" 27 tracking_url: orders.trackingUrl 28 }, 29 badge_count: unreadCount 30 }; 31 } 32}
  • Pros: Optimized performance for specific clients. The Frontend team can "own" the BFF and iterate fast without waiting for Backend teams to change core microservices.
  • Cons: Code duplication. You might write similar logic in the Web BFF and Mobile BFF.

3. GraphQL (The "Client-Defined" Pattern)

GraphQL flips the model. Instead of the server defining what is returned, the client defines it.

How it Works

The server exposes a graph of all possible data. The client sends a query:

1query { 2 user(id: "123") { 3 firstName 4 orders(limit: 1) { 5 status 6 } 7 } 8}
  • Pros: Zero over-fetching. Frontends are completely unblocked; they can query whatever they want without asking backend devs for new endpoints.
  • Cons: Complexity. Preventing malicious users from requesting nested queries 100 levels deep (DoS attack) requires sophisticated complexity analysis and rate limiting. Caching is also much harder than REST.

Comparison Matrix: Which one to choose?

ScenarioRecommended PatternWhy?
Simple web app (Monolith)Direct REST APIDon't overengineer. Keep it simple.
Enterprise MicroservicesAPI GatewayYou need a centralized place for Auth, SSL, and Routing.
Separate Web & Mobile TeamsBFF (Backend for Frontend)Allows mobile devs to optimize their API independently of web requirements.
Data-Heavy DashboardGraphQLDashboards often need random bits of data from 50 sources. GraphQL shines here.
Public Developer APIREST with GatewayPublic devs want standard, predictable REST endpoints, not a custom BFF.

Conclusion

There is no "One Pattern to Rule Them All."

  • Use an API Gateway to protect your microservices.
  • Put a BFF behind that Gateway if your Mobile and Web apps are drifting apart in requirements.
  • Use GraphQL if you have a highly interconnected data model and want to empower frontend autonomy.

In 2026, the most successful architectures often mix these: A generic API Gateway that routes traffic to specific BFFs (one of which might be a GraphQL server!).

Share this article

Inspired by This Blog?

Join our newsletter

Get product updates and engineering insights.

JJ

Jayesh Jain

Jayesh Jain is the CEO of Tirnav Solutions and a dedicated business leader defined by his love for three pillars: Technology, Sales, and Marketing. He specializes in converting complex IT problems into streamlined solutions while passionately ensuring that these innovations are effectively sold and marketed to create maximum business impact.

Optimize your API Layer.

Experiencing slow mobile loads? We specialize in building high-performance BFF layers for enterprise apps.

Let’s Talk

Related Posts