GraphQL中delegateToSchema不使用自定义executor问题求助
问题原因及修复方案
核心问题1:方法导入不匹配
你使用的v7版本中,graphql-tools包导出的delegateToSchema是旧版遗留实现,无法正确识别wrapSchema生成的绑定了executor的包装Schema,需要替换为从@graphql-tools/delegate导入的对应方法。
核心问题2:重复初始化远程Schema
你在字段解析器中每次请求都调用makeRemoteSchema,会重复触发内省请求,不仅性能损耗极大,还会导致Schema绑定异常,需要改为服务启动阶段一次性初始化远程Schema。
核心问题3:请求参数语法笔误
你提供的初始代码中,got调用的参数少了一个右花括号,会导致请求体格式错误:
// 错误写法 return got.post('http://localhost:6677/graphql', {json: {query, variables}).json(); // 正确写法 return got.post('http://localhost:6677/graphql', {json: {query, variables}}).json();
修复后可运行代码
导入与全局初始化
const { wrapSchema, introspectSchema } = require('@graphql-tools/wrap'); const { delegateToSchema } = require('@graphql-tools/delegate'); // 替换导入源 const got = require('got'); const { print } = require('graphql'); const executor = async ({ document, variables }) => { const query = typeof document === 'string' ? document : print(document); return got.post('http://localhost:6677/graphql', { json: { query, variables } }).json(); }; // 服务启动时只初始化一次远程Schema,不要放在解析器中重复执行 let remoteSchema; const initRemoteSchema = async () => { const introspectedSchema = await introspectSchema(executor); remoteSchema = wrapSchema({ schema: introspectedSchema, executor }); }; // 服务启动逻辑中先调用initRemoteSchema,等初始化完成再启动GraphQL服务
字段解析器
const conversations = async ({ id }, _, context, info) => { const result = await delegateToSchema({ schema: remoteSchema, // 直接传入预初始化的包装后Schema operation: 'query', fieldName: 'conversations', args: { consultationParticipantId: id, }, context, info }); return result; };
额外注意事项
- v6/v7版本都不支持直接给
delegateToSchema传入{schema, executor}的配置对象,必须传入wrapSchema处理后的标准GraphQLSchema实例 - 排查问题时可在executor中打印
query和variables参数,确认代理请求内容是否符合预期
内容的提问来源于stack exchange,提问作者Tim Scott
相关产品推荐
相关产品推荐

