Design and Practice of RPC‑Based Backend‑for‑Frontend (BFF)
This article explains the motivation behind Backend‑for‑Frontend, compares naive and decoupled BFF implementation patterns, evaluates RESTful, GraphQL and RPC options, and presents a TypeScript‑centric RPC‑BFF solution with schema‑driven validation, type inference, introspection, code generation and advanced optimizations such as merge, batch, streaming, caching and deduplication.
With the rapid growth of multi‑terminal applications, data‑exchange complexity between front‑end and back‑end has increased, prompting the emergence of the Backend‑for‑Frontend (BFF) pattern, which tailors APIs to the specific needs of each client type.
The need for BFF is driven by two industry trends: the proliferation of diverse hardware terminals and the shift toward micro‑service and middle‑platform architectures, both of which raise the cost of data aggregation for downstream consumers.
Two main implementation modes are described: the naïve mode , where the back‑end team solely owns the BFF service, and the decoupled mode , where the front‑end team develops and maintains its own BFF, allowing each team to focus on its domain.
Technology options for BFF are examined. RESTful APIs are simple but misaligned with front‑end data needs; GraphQL offers flexible queries but suffers from type‑system duplication and limited streaming support; RPC provides function‑style calls with lower conceptual overhead.
The article then introduces an RPC‑BFF design built on TypeScript. A custom ObjectType schema retains type information at runtime, enabling validation, type‑infer and introspection. Example schema definitions include:
type UserType = { id: string; name: string; age: number; }
const user: UserType = { id: 'user_id_01', name: 'Jade', age: 18 };
import { ObjectType } from '@ctrip/rpc-bff';
class User extends ObjectType { constructor() { super(...arguments); this.id = String; this.name = String; this.age = Number; } }Using the schema, RPC functions are declared with Api and automatically generate matching client code via a CLI configuration ( rpc.config.js ). The generated client offers end‑to‑end type‑safe calls, natural throw / try‑catch error handling, and embeds documentation directly in code comments.
RPC‑BFF also provides advanced capabilities: automatic merge, batch and streaming of multiple RPC calls to reduce request latency; cache and deduplication to avoid redundant network traffic; and version‑aware interface compatibility checks that surface type errors at compile time.
In summary, the RPC‑BFF approach combines the simplicity of naïve function definitions with powerful schema‑driven features, delivering a robust, type‑safe, and performance‑optimized BFF solution for modern front‑end teams.
Ctrip Technology
Official Ctrip Technology account, sharing and discussing growth.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.