Spring Cloud Gateway中GraphQL联邦配置问题求助
已搭建Spring Cloud Server及注册到Eureka的Node.js/TypeScript微服务(Node端使用eureka-js-client实现Eureka注册),在Spring Boot中引入以下依赖启用GraphQL联邦:
<dependency> <groupId>com.apollographql.federation</groupId> <artifactId>federation-graphql-java-support</artifactId> <version>${federation-graphql-java-support.version}</version> </dependency>
但当前无法识别Node服务的/graphql接口及Schema,需求为:让Node.js的GraphQL Schema被Spring Cloud识别,或在Spring Cloud体系中构建Apollo层,整合所有关联Node微服务的子图生成超级图,通过API网关对外提供统一访问(理想状态是汇总所有服务的GraphQL Schema生成超级图,统一通过网关访问)。
方案一:让Spring Cloud Gateway识别Node子图并构建联邦超级图
1. 确保Node.js服务Schema符合联邦规范
Node端必须使用Apollo Federation定义可联邦的Schema,确保包含_service查询字段(联邦服务发现的核心):
import { buildSubgraphSchema } from '@apollo/federation'; import { ApolloServer } from 'apollo-server-express'; const typeDefs = ` type Product @key(fields: "id") { id: ID! name: String! } extend type Query { product(id: ID!): Product } `; const resolvers = { /* 实现对应的解析逻辑 */ }; const server = new ApolloServer({ schema: buildSubgraphSchema([{ typeDefs, resolvers }]), });
启动Node服务后,访问http://<node-service-host>:<port>/graphql,执行查询{ _service { sdl } },确认能返回正确的SDL(Schema定义语言)内容。
2. 在Spring Boot中实现子图Schema收集与合并
- 通过
DiscoveryClient从Eureka获取所有注册的Node服务实例列表; - 编写工具类遍历实例,调用其
/graphql接口执行{ _service { sdl } }查询,收集所有子图的SDL; - 使用
federation-graphql-java-support合并SDL生成超级图:
import com.apollographql.federation.graphqljava.Federation; import graphql.schema.GraphQLSchema; import graphql.schema.idl.SchemaGenerator; import graphql.schema.idl.SchemaParser; import graphql.schema.idl.TypeDefinitionRegistry; // 假设已收集到所有子图的sdl字符串列表 List<String> subgraphSdls TypeDefinitionRegistry registry = new TypeDefinitionRegistry(); for (String sdl : subgraphSdls) { registry.merge(new SchemaParser().parse(sdl)); } GraphQLSchema supergraphSchema = Federation.transform(new SchemaGenerator().makeExecutableSchema(registry)) .build();
3. 网关暴露超级图接口
将生成的超级图Schema集成到Spring GraphQL中,通过Spring Cloud Gateway路由到Spring GraphQL的默认入口/graphql,对外提供统一访问。
方案二:使用Apollo Router作为独立网关层整合子图
若不想在Spring Boot中手动处理Schema合并,推荐使用Apollo Router作为GraphQL联邦网关,与Spring Cloud体系集成:
1. 配置Apollo Router
编写router.yaml,通过插件实现Eureka服务发现:
supergraph: composition: subgraphs: node-service: routing_url: http://${service-name}:${port}/graphql plugins: - id: eureka config: server_url: http://<eureka-server-host>:<port>/eureka/ service_name: node-service
启动Apollo Router后,它会自动从Eureka获取Node服务实例、拉取子图Schema并合并为超级图(默认端口4000)。
2. Spring Cloud Gateway转发配置
在网关中添加路由规则,将外部GraphQL请求转发到Apollo Router:
spring: cloud: gateway: routes: - id: graphql-supergraph uri: http://<apollo-router-host>:4000/ predicates: - Path=/graphql/**
- 所有子图服务必须严格遵循Apollo Federation规范,确保
_service查询可用,实体定义包含@key等联邦指令; - 若选择Spring Boot手动合并Schema,需实现定时刷新逻辑,在Eureka服务实例变化时重新拉取并更新超级图;
- Apollo Router作为官方网关,支持缓存、认证、监控等更多联邦特性,是生产环境的推荐方案。
内容的提问来源于stack exchange,提问作者Robin Malhotra

