How Duo-GraphQL Transforms BFF Architecture for Scalable Microservices
Facing tangled microservice calls and heavy front‑end data stitching, Fangdd’s engineering team evolved from monolithic PHP to a multi‑layered microservice architecture, introducing Duo‑GraphQL to unify data via GraphQL providers, a BFF layer, and optimized engine, dramatically improving development speed and performance.
During a Scrum requirement review, a front‑end developer used Duo‑GraphQL to write GraphQL queries on the fly, demonstrating the need for a more efficient data‑access solution.
Architecture Evolution Background
Fangdd’s technology grew from a single PHP monolith to hundreds of microservices supporting multiple front‑ends (APP, H5, mini‑programs) across three product lines (Agent, Business, Customer). The first evolution split the monolith using Nginx + Thrift, resulting in a coarse‑grained distributed service layer with tangled call chains and heavy Thrift client coupling.
The second evolution introduced a RESTful access layer and Dubbo‑governed microservices, clarifying service boundaries and adopting DevOps practices such as CI/CD, virtualization, and internal DNS routing.
As versions accumulated, both the access layer and business services became bloated, with APIs returning ever‑growing payloads (e.g., a property‑list API with 75 fields, though most UI pages need fewer than 10).
To address these challenges, the team adopted a modern front‑end stack (Node.js) and a Backend‑For‑Frontend (BFF) pattern, allowing front‑end teams to define required data while back‑end engineers focus on domain services.
GraphQL Introduction
GraphQL, created by Facebook in 2012 and open‑sourced in 2015, provides a flexible query language and type system. Its advantages include precise data fetching, single‑request multiple‑resource retrieval, strong developer tooling, schema‑driven API evolution, and reuse of existing code and data.
GraphQL Advantages
Request exactly the data you need.
Fetch multiple resources with a single request.
Describe the entire type system.
Powerful developer tools.
API evolution without versioning.
Leverage existing data and code.
GraphQL Disadvantages
Complex schema and resolver design increase maintenance cost.
Potential N+1 or circular request problems.
Learning curve for the unique query syntax and IDE support.
Various other practical concerns.
Who Uses GraphQL
Many companies have adopted GraphQL for its data‑centric benefits (illustrated in the original source).
GraphQL Implementation Landscape
Apollo GraphQL is the most mature JavaScript ecosystem, offering a full stack of services (some advanced features are paid). Other language implementations exist, but integrating them into distributed microservice environments can be challenging.
Common pitfalls include monolithic schema deployment, lack of domain boundaries, and insufficient documentation when auto‑generating schemas from RESTful services.
The Birth of Duo‑GraphQL
Recognizing GraphQL’s fit for data‑driven C‑end products, Fangdd sought a solution that integrates with existing development, testing, and release pipelines while reusing infrastructure. Duo‑GraphQL leverages the open‑source Duo‑Doc project, which extracts API signatures and documentation from code, providing ready‑made schema and resolver information.
The core idea is to combine traditional microservice APIs into a unified GraphQL graph using Duo‑Doc’s extracted metadata.
Our Goals
Free the BFF layer from tedious data‑assembly tasks, allowing developers to focus on higher‑value work.
Duo‑GraphQL Architecture
1. GraphQL Provider (Data Supply Side)
Each provider is a standard RESTful service that defines two response types: a standard view representing domain entities (e.g., property, agent) and a non‑standard view for composite data (e.g., recommendation lists). Standard views are annotated with @SchemaProvider to generate schema fields and bind resolvers.
2. GraphQL Engine
The engine consists of:
graphql‑java for query parsing and execution.
Duo‑GraphQL module for provider registration, schema generation, data‑fetcher binding, request merging, caching, asynchronous orchestration, custom extensions, monitoring, and multi‑schema support.
3. Access Layer
To accommodate platforms that prefer RESTful APIs (Android/iOS), the access layer stores GraphQL queries and exposes them as uniquely named REST endpoints, handling parameter translation and delegating execution to the Duo‑GraphQL engine.
4. Front‑End (Consumer)
Front‑end applications issue HTTP requests to Duo‑GraphQL, which fully complies with the GraphQL spec and supports Apollo‑client protocols.
Implementation Details
GraphQL Provider Build Process
During build, Duo‑Doc (via a Maven plugin) extracts API signatures into an api.json file, providing the schema and resolver data needed by Duo‑GraphQL.
Duo‑GraphQL Startup
Subscribes to a registration center (ZooKeeper or Redis) for provider changes.
Fetches provider metadata and corresponding API definitions.
Constructs the unified schema and binds data fetchers.
Provider Registration
Providers publish their version and address via HTTP to Duo‑GraphQL, which updates the registration center (Redis or ZooKeeper).
Optimization Strategies
Concurrent requests using CompletionStage in DataFetchers.
Query pre‑compilation and caching.
Request merging to eliminate redundant calls.
N+1 problem mitigation via graphql‑java strategies.
Inner Providers for common views (e.g., administrative regions, subway lines).
HTTP/2 support for RESTful providers to reduce connection overhead.
Subscription Support
Implemented using Redis PUB/SUB; providers register via Redis, enabling lightweight real‑time updates.
Performance
Duo‑GraphQL is heavily used in Fangdd’s C‑end products, achieving 100% SLA over the past week with 95th‑percentile latency of 20.3 ms and 99.9th‑percentile of 65.3 ms, comparable to hand‑crafted traditional APIs.
Conclusion
GraphQL is a double‑edged sword: when used correctly it dramatically boosts development efficiency and reduces technical debt; when misused it can become a performance bomb. Through extensive experimentation, Fangdd distilled best practices and open‑sourced Duo‑GraphQL and Duo‑Doc for the community.
Source code: https://github.com/fangdd-open/duo-graphql
Related project Duo‑Doc: https://github.com/fangdd-open/duo-doc
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Fangduoduo Tech
Sharing Fangduoduo's product and tech insights, delivering value, and giving back to the open community.
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.
