GraphQL网关是联邦架构的核心组件。它接收客户端的查询,根据Supergraph的查询计划把查询分发给对应的子图,最后把各子图的结果组装成统一的响应。
Apollo Gateway是Apollo联邦的官方网关实现:
import { ApolloGateway } from '@apollo/gateway'; import { ApolloServer } from '@apollo/server'; const gateway = new ApolloGateway({ supergraphSdl: await fetchSupergraphSdl(), // 实体缓存,减少跨服务请求 buildServiceDefinition: ({ url }) => new IntrospectAndCompose({ subgraphUrl: url }), }); const server = new ApolloServer({ gateway, // 网关不需要解析器,解析逻辑在子图 });
GraphQL Mesh是The Guild的替代方案,它可以把任何API(REST、gRPC、SOAP、数据库)自动包装成GraphQL Schema,不需要各服务原生支持GraphQL。适合需要快速统一异构后端的场景。
# mesh.config.yaml sources: - name: UsersAPI handler: openapi: source: ./swagger/users.yaml - name: PostsAPI handler: openapi: source: ./swagger/posts.yaml - name: CommentsAPI handler: graphql: endpoint: http://comments-service:4000/graphql transforms: - renameFields: renames: UsersAPI.User.username -> UsersAPI.User.name
Mesh在启动时合并所有源Schema,生成一个统一的GraphQL端点。客户端不需要知道后端是REST还是GraphQL——Mesh处理所有的转换。
Apollo GraphOS(前身为Apollo Engine/Studio)是Apollo的云平台,提供:
// Apollo Server连接GraphOS const server = new ApolloServer({ typeDefs, resolvers, plugins: [ // 上报Schema和性能数据到GraphOS ApolloServerPluginUsageReporting({ graphID: 'my-app', apiKey: process.env.APOLLO_KEY, }), // APQ缓存存储在GraphOS云端 ApolloServerPluginInMemoryLruCache(), ] });
AWS AppSync是AWS的托管GraphQL服务。它支持实时订阅(DynamoDB触发)、离线数据同步、以及与Lambda函数的集成。如果你已经在AWS生态中,AppSync省去了自建GraphQL服务的工作。
// AppSync自动处理解析器的部署和执行 // Schema在AppSync控制台中定义 type Query { getUser(id: ID!): User @aws_iam @aws_cognito_user_pools }
在大型组织中,多个团队可能各自维护GraphQL服务。Schema注册中心集中管理所有服务的Schema,提供变更审计和兼容性检查。
Apollo Schema Registry(GraphOS的一部分)是当前最成熟的方案。每次子图部署时,Schema自动注册到GraphOS,网关从GraphOS拉取最新的Supergraph。
# 使用Apollo Rover CLI注册Schema rover subgraph publish my-app@prod \ --schema ./schema.graphql \ --routing-url http://users-service:4001/graphql \ --name users
GraphQL Inspector(Schema-aware linting和breaking change检测)可以在CI中检查Schema变更是否破坏了现有查询:
# 检查Schema变更是否breaking graphql-inspector diff ./old-schema.graphql ./new-schema.graphql # 检查操作是否与Schema兼容 graphql-inspector validate './src/**/*.graphql' './schema.graphql'
| 需求 | 推荐方案 |
|---|---|
| 联邦架构网关 | Apollo Gateway |
| 统一异构API | GraphQL Mesh |
| 云端GraphQL托管 | Apollo GraphOS 或 AWS AppSync |
| Schema版本管理 | Apollo Rover + GraphOS |
| Schema变更审计 | GraphQL Inspector + CI |
对于中小型项目,自建GraphQL服务就够了,不一定需要托管平台。但当项目规模增长到多个团队、多个子图、多个部署环境时,托管平台的管理能力就变得不可或缺——手动管理Schema的版本和兼容性很快会成为瓶颈。
网关每收到一个查询,都要先根据 Supergraph 生成查询计划,再分发执行。查询计划的生成本身有 CPU 开销,所以生产网关都会缓存查询计划——以查询文本哈希为键。这带来一个工程细节:查询越规范,计划缓存命中率越高。客户端拼接出来的查询(字段顺序、空白不同)会导致哈希不同,缓存命中率低。配合持久化查询或代码生成固定查询文本,可以让计划缓存发挥最大价值。
另一个性能要点是网关的实体解析合并。跨子图的实体请求可以批量发送:订单子图返回 100 个订单,网关把 100 个 userId 合并成一次用户子图调用,而不是 100 次。这个能力由网关自动完成,但前提是子图的实体解析器实现了批量接口(接收数组),否则网关只能逐个调用。
Schema 注册中心的核心价值在多人多环境协作:
# 发布前检查:新 Schema 是否破坏已有操作 rover subgraph check my-app@prod --name users --schema ./schema.graphql
自建网关和注册中心的好处是数据不出内网、无按量计费,坏处是要自己维护高可用、版本存储、权限系统——这些往往被低估。托管方案省掉运维,但引入供应商依赖和数据出网。折中做法:小规模用自建网关加 Schema 文件入库,规模上来或团队开始为治理头疼时再上托管。判断信号很简单:当"查一下这个 Schema 是谁改的"变成每周都会发生的需求时,就该上注册中心了。
网关还有一层安全职责:它是所有客户端请求的入口,限流、鉴权、查询白名单都可以在这里统一做,而不必在每个子图重复实现。把安全策略放在网关,配合子图自身的字段级授权,既保证统一入口有防线,又避免网关变成过于庞大的"上帝层"。设计时注意区分:网关管"谁能进"和"一次能查多贵",子图管"进了以后能看哪些字段"。