Overview
The Backend for Frontend (BFF) pattern is mandatory for all Ascendion mobile applications. Mobile clients do not share an API with web clients. A purpose-built mobile API layer aggregates microservice responses, applies field selection, implements mobile-appropriate pagination, and enforces mobile-specific authentication flows.
API Style Selection
GraphQL is the preferred default for new BFF implementations. Field selection is native to the protocol — the mobile client requests only the fields it renders. A single GraphQL query replaces multiple REST round trips for screen composition. Apollo Kotlin and Apollo iOS generate type-safe client code from the GraphQL schema, eliminating serialisation errors at the integration boundary. GraphQL subscriptions provide real-time updates without separate WebSocket management.
REST with Mobile Conventions is adopted when the backend team has strong REST expertise and limited GraphQL experience. Mobile-specific conventions are mandatory: cursor-based pagination (opaque cursor, not page number — page number breaks when items are inserted mid-pagination), field selection via ?fields= parameter, batch endpoints for related resources, conditional requests with ETag/If-None-Match headers, and Brotli compression for response bodies.
gRPC with Protocol Buffers supplements the BFF for high-frequency low-latency data streams: real-time location tracking, financial order book updates, live auction bidding, real-time chat. Protobuf binary encoding is 3-10× more compact than JSON for equivalent data. Bidirectional streaming eliminates the polling model for real-time features.
Repository-to-API Mapping
Each Repository method maps to exactly one BFF operation. Aggregation is the BFF's responsibility — the Repository does not compose multiple API calls to build a domain model. This 1:1 mapping enables consumer-driven contract testing with Pact: the mobile client defines the contract it expects from each Repository method, and CI verifies the BFF satisfies it before any backend deployment.
Push Notification Architecture
APNs (iOS) and FCM (Android) are the delivery mechanisms for push notifications. The BFF maintains device token registration and handles token rotation (410 Gone from APNs triggers immediate token deletion). Push payloads must never contain sensitive data — they contain a notification_id only. The mobile app calls the BFF to fetch actual content after notification open. Silent pushes (background-content-available on iOS, high-priority data message on FCM) trigger background delta sync without user-visible notification.
Anti-Patterns to Avoid
⚠ 1. Shared Web and Mobile API
Mobile consuming the same REST API designed for web. Web APIs return full resource representations (47 fields); the mobile screen renders 8. Battery, bandwidth, and parse time wasted on 39 unused fields.
Hover to see the fix ↻
↺ Correct Approach
Purpose-built mobile BFF. Field selection reduces payload 40-70%. Single round trip replaces multiple sequential requests. Mobile-specific authentication (PKCE) enforced at the BFF boundary.
⚠ 2. Offset-Based Pagination for Infinite Scroll
GET /transactions?page=3&limit=20. When a new transaction is inserted before page 3 is fetched, items shift and the user sees a duplicate or skipped transaction.
Hover to see the fix ↻
↺ Correct Approach
Cursor-based pagination. GET /transactions?after=eyJpZCI6IjEyMyJ9&limit=20. Cursor is opaque — computed from the last item's ID or timestamp. Stable regardless of concurrent inserts.
Flowchart
%%{init:{'theme':'base','themeVariables':{'fontSize':'14px','fontFamily':'IBM Plex Sans, system-ui, sans-serif','primaryColor':'#DBEAFE','primaryTextColor':'#1e3a5f','primaryBorderColor':'#2563EB','lineColor':'#374151','clusterBkg':'#F9FAFB','clusterBorder':'#D1D5DB','edgeLabelBackground':'#FFFFFF'},'flowchart':{'curve':'orthogonal','padding':30,'nodeSpacing':65,'rankSpacing':75,'useMaxWidth':true}}}%%
flowchart LR
subgraph Mobile["📱 Mobile App"]
REPO2["Repository
Interface"]
GQL["Apollo Client
GraphQL / REST"]
end
subgraph BFF["⚡ Mobile BFF"]
GW["API Gateway
Field Selection
Mobile Auth (PKCE)"]
AGG["Aggregation Layer
Compose responses
Delta sync support"]
CACHE["Response Cache
ETag / If-None-Match
Brotli compression"]
end
subgraph Services["🏗 Backend Microservices"]
US["User Service"]
TS["Transaction Service"]
PS["Product Service"]
PUSH["Push Service
APNs / FCM"]
end
REPO2 --> GQL --> GW
GW --> AGG --> US & TS & PS
AGG --> CACHE
PUSH -->|"Silent push
notification_id only"| Mobile
style Mobile fill:#E3F2FD,stroke:#1565C0
style BFF fill:#FFF8E1,stroke:#F57F17
style Services fill:#E8F5E9,stroke:#1B5E20
References
- Newman, Sam — Backends for Frontends Pattern. samnewman.io/patterns/architectural/bff
- GraphQL Foundation — GraphQL Specification. spec.graphql.org
- Google — gRPC Documentation. grpc.io/docs
- Pact Foundation — Consumer-Driven Contract Testing. docs.pact.io
- RFC 7807 — Problem Details for HTTP APIs. tools.ietf.org/html/rfc7807
Mobile Engineering Reference
← Mobile Development