How NetEase Cloud Music Decoupled Frontend and Backend with a GraphQL‑Powered BFF

This article explains how NetEase Cloud Music tackled the tight coupling between frontend UI and backend services by introducing a Backend‑For‑Frontend layer built on GraphQL, detailing the architectural choices, low‑code editor, custom directives, deployment pipeline, and the resulting improvements in scalability and developer productivity.

NetEase Cloud Music Tech Team
NetEase Cloud Music Tech Team
NetEase Cloud Music Tech Team
How NetEase Cloud Music Decoupled Frontend and Backend with a GraphQL‑Powered BFF

Background: Decoupling Frontend and Backend

NetEase Cloud Music’s traditional front‑end/back‑end collaboration required the backend to assemble and adapt data for each page, causing deep contract dependencies and high communication overhead when UI fields changed. To reduce interface calls and avoid extensive data transformation on the client, a dedicated middle‑service was created to aggregate data from multiple domain services.

Why Choose GraphQL?

FaaS vs GraphQL

Two common BFF implementations are NodeJS‑based FaaS and GraphQL. The FaaS approach demands extensive Node infrastructure, monitoring, and deployment expertise, and introduces a learning curve for non‑web developers. GraphQL, by contrast, offers a DSL that is easier to adopt, allows a unified execution engine, and keeps complexity under control.

What is GraphQL?

GraphQL consists of a query language (DSL) for describing required fields and parameters, and a runtime that traverses a graph of data sources to resolve those fields. The runtime parses a query, identifies the nodes to fetch, dispatches RPC calls, and returns a result matching the query shape.

Implementing GraphQL requires three components: a GraphQL engine, type definitions (schema), and resolvers that map schema fields to backend RPC calls.

Applying GraphQL at Cloud Music

Key challenges included enabling frontend engineers to set up a reliable GraphQL runtime, lowering the learning barrier for GraphQL syntax, integrating with existing CI/CD pipelines, and extending GraphQL to cover at least 70% of BFF scenarios.

Low‑code tooling was introduced so frontend developers could configure GraphQL without deep backend knowledge.

GitLab stores GraphQL queries, schemas, and resolver definitions, managed through the Febase platform.

Custom directives extend GraphQL’s capabilities for complex RPC parameter construction and flexible response transformation.

Distributed Architecture Design

Requests still enter via the existing RESTful API gateway, preserving traffic control, fallback, and static rendering. The gateway forwards requests to a GraphQL cluster where the built‑in engine translates URLs to GraphQL queries, dispatches RPC calls, and returns assembled data. Each GraphQL service runs in its own cloud‑native container, allowing pod scaling based on CPU usage.

Fast Schema Generation from Contracts

Backend contract definitions (Java RPC interfaces) are stored in a contract management platform as JSON. A converter maps Java types to GraphQL types, generating type.schema files automatically and committing them to the Git repository.

{
  "type": "rpc",
  "clzName": "com.netease.music.api.SongService",
  "methodName": "getSongById",
  "params": []
}

The corresponding GraphQL schema:

type Query {
  song: Song
}

type Song {
  id: ID
  name: String
}

Low‑Code GraphQL Editor

The Febase platform provides a visual editor built on graphql‑voyager that lets developers select fields, configure directives, and generate the underlying AST. The editor supports both low‑code (field selection) and pro‑code (manual query editing) modes.

Custom Directives for Complex Scenarios

Two custom directives were added: @param – Executes a script before the query to assemble complex RPC parameters from multiple sources (e.g., HTTP query, cookies). @convert – Executes a script after the query to transform the response into a shape required by the UI.

Both directives invoke Groovy scripts, allowing flexible data manipulation while keeping the GraphQL schema stable.

Standard Development Workflow

GraphQL applications follow the same CI/CD process as other frontend services: feature branches, automated syntax checks via graphql‑language‑service‑interface, review gates, and one‑click production deployment. Errors are diagnosed using getDiagnostics, and request traces are recorded for debugging.

Conclusion

By adopting a GraphQL‑based BFF, Cloud Music reduced frontend‑backend coupling, lowered communication overhead, and increased interface reusability. Over six months, more than 160 data interfaces were created, many serving high‑traffic scenarios. Future work will share deeper engine details and additional GraphQL use cases.

cloud nativemicroservicesbackend developmentLowCodeBFFGraphQL
NetEase Cloud Music Tech Team
Written by

NetEase Cloud Music Tech Team

Official account of NetEase Cloud Music Tech Team

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.