GraphQL网关中如何合并来自两个子Schema的关联类型字段?
问题原因
你仅配置了User类型的合并规则,但Contacts作为User的嵌套对象,网关未收到明确指令去从多服务拉取它的字段。默认情况下,网关只会从获取User的服务(此处为Service2)请求Contacts数据,不会自动触发Service1的调用去获取primary字段。
解决方案
需要为Contacts类型添加合并规则,同时确保User类型的selectionSet包含Contacts的唯一标识(id),让网关能通过该标识向对应服务请求Contacts的指定字段。
修改后的网关配置
import { stitchSchemas } from "@graphql-tools/stitch" ... const schema = stitchSchemas({ subschemas: [ { schema: service1Schema, executor: service1Executor, merge: { User: { fieldName: "getUser", // 新增:在selectionSet中包含contacts.id,让网关获取Contacts的唯一标识 selectionSet: "{ id contacts { id } }", args: (originalObject) => ({ input: { id: originalObject.id } }), }, // 新增Contacts类型合并规则,指定该服务提供primary字段 Contacts: { fieldName: "getUser", selectionSet: "{ id }", // 通过Contacts.id关联所属User的id(假设二者一致) args: (contact) => ({ input: { id: contact.id } }), fields: { primary: true } } } }, { schema: service2Schema, executor: service2Executor, merge: { User: { fieldName: "getUser", selectionSet: "{ id contacts { id } }", args: (originalObject) => ({ input: { id: originalObject.id } }), }, // 新增Contacts类型合并规则,指定该服务提供secondary字段 Contacts: { fieldName: "getUser", selectionSet: "{ id }", args: (contact) => ({ input: { id: contact.id } }), fields: { secondary: true } } } }, ] })
优化建议(可选)
如果希望逻辑更清晰,建议在两个服务中新增专门的getContacts查询:
Service1/Service2新增Query定义
Query { getContacts(input: GetContactsInput!): Contacts } input GetContactsInput { id: ID! }
修改Contacts合并规则
Contacts: { fieldName: "getContacts", selectionSet: "{ id }", args: (contact) => ({ input: { id: contact.id } }), fields: { primary: true } // Service1用primary,Service2用secondary }
这种方式避免了依赖User查询获取Contacts数据,逻辑更独立。
验证逻辑
修改后网关执行查询时:
- 通过User合并规则获取User基础信息及Contacts.id
- 针对
primary字段,调用Service1的查询获取对应值 - 针对
secondary字段,调用Service2的查询获取对应值 - 合并两个服务的Contacts字段结果,返回完整数据
内容的提问来源于stack exchange,提问作者savoryparsnip7
相关产品推荐
相关产品推荐

