加载GraphQL文件构建Apollo-Server联邦Schema出现类型错误如何解决
错误根因
你调用loadSchema方法默认返回的是GraphQLSchema实例对象,而gql标签仅接收字符串/模板字符串类型的SDL内容,二者类型不匹配触发了报错。同时buildSubgraphSchema入参要求的typeDefs是DocumentNode类型,也和GraphQLSchema类型不兼容。
解决方法
推荐两种可行方案,优先选择第一种:
方案1:使用loadTypeDefs直接加载符合要求的类型定义
这是最贴合场景的方案,loadTypeDefs会直接返回DocumentNode类型的结果,无需额外转换即可传入buildSubgraphSchema使用:
import { buildSubgraphSchema } from '@apollo/federation'; // 纯.graphql后缀的SDL文件使用GraphQLFileLoader更适配 import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader'; import { loadTypeDefs } from '@graphql-tools/load'; import { ApolloServer } from 'apollo-server'; // ...其余原有引入和代码 const typeDefs = await loadTypeDefs(`${__dirname}/auth.graphql`, { loaders: [new GraphQLFileLoader()], }); const server = new ApolloServer({ schema: buildSubgraphSchema([ { typeDefs, // 无需额外套gql标签 resolvers, } ]), })
方案2:转换loadSchema返回的结果
如果你必须保留loadSchema的调用,可将返回的GraphQLSchema实例转换为SDL字符串后再用gql标签处理:
import { buildSubgraphSchema } from '@apollo/federation'; import { CodeFileLoader } from '@graphql-tools/code-file-loader'; import { loadSchema } from '@graphql-tools/load'; import { ApolloServer, gql } from 'apollo-server'; import { printSchema } from 'graphql'; // 引入graphql自带的打印schema方法 // ...其余原有引入和代码 const schema = await loadSchema(`${__dirname}/auth.graphql`, { loaders: [new CodeFileLoader()], }); // 先转成SDL字符串再用gql生成DocumentNode const typeDefs = gql(printSchema(schema)); const server = new ApolloServer({ schema: buildSubgraphSchema([ { typeDefs, resolvers, } ]), })
注意事项
- 若你加载的是
.graphql后缀的纯SDL文件,优先使用GraphQLFileLoader而非CodeFileLoader,后者主要用于加载TS/JS代码文件中导出的schema定义 gql标签仅用于处理字符串格式的SDL内容,不要对已经是DocumentNode类型的结果重复套gql标签
内容的提问来源于stack exchange,提问作者Hazem Alabiad
相关产品推荐
相关产品推荐

