使用 ApolloServer 从 graphql-import 迁移到 graphql-tools 时出现问题,指令停止工作
Trouble migrating from graphql-import to just graphql-tools with ApolloServer, directives cease to work
我的困境开始于一个简单的愿望,即想将我的 graphql 模式从单个 .graphql 文件扩展到多个文件,这样我就可以更好地组织模式,这样它就不会增长到一个失控的大文件。
我的原始布局非常简单,我在 schema.graphql
文件中有一个工作模式。我可以使用 graphql-import 库中的 importSchema('server/schema.graphql')
将其解析为字符串,该库现已弃用 https://github.com/ardatan/graphql-import
他们提到它已在最新版本中合并到 graphql-tools
并在此处提供迁移教程 https://www.graphql-tools.com/docs/migration-from-import 该教程看起来非常简单,因为他们的第一个示例几乎准确地说明了我的代码看起来像(除了我不使用 es6 导入但老式的要求):
import { importSchema } from 'graphql-import';
import { makeExecutableSchema } from 'graphql-tools';
const typeDefs = importSchema(join(__dirname, 'schema.graphql'));
const resolvers = {
Query: {...}
};
const schema = makeExecutableSchema({ typeDefs, resolvers });
然后他们说要修改它,只需进行这些更改
import { loadSchemaSync } from '@graphql-tools/load';
import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader';
import { addResolversToSchema } from '@graphql-tools/schema';
const schema = loadSchemaSync(join(__dirname, 'schema.graphql'), { loaders: [new GraphQLFileLoader()] });
const resolvers = { Query: {...} };
const schemaWithResolvers = addResolversToSchema({
schema,
resolvers,
});
我做了这些更改,但重要的区别是他们不再在他们的示例中使用 makeExecutableSchema()
,这对我来说非常重要,因为我需要包含指令。我现在如何处理架构?我如何声明指令?他们的指令文档仍然使用 makeExecutableSchema
但我不能再使用它了,因为新的 loadSchemaSync
函数 returns 一个对象而不是我需要传递给 typeDefs
的字符串文字在 makeExecutableSchema
我正在使用 apollo-server,所以似乎一个可能的解决方法是在 apollo-server 构造函数中声明指令,然后将这个新的 schemaWithResolvers
作为模式传入
const server = new ApolloServer({
schema, //this includes now the returned value of using addResolversToSchema()
schemaDirectives : {
auth:AuthDirective,
authRole: AuthRoleDirective
}
context : ({req}) => //dostuff,
});
这允许我的服务器 运行,并且我可以执行查询和更改,但是,我的指令不再有效,并且我不再对受保护的查询进行身份验证。
我想要一种方法来导入我的 .graphql 文件并将其解析为一个字符串,这样我就可以在 typeDefs
中使用它,就像我以前使用 importSchema() 一样,或者一种不使用 importSchema() 来声明我的目录的方法makeExecutableSchema() 以便他们再次继续工作!
我查阅了文档并查看了其他库,但到目前为止我一直在做空,非常感谢任何提示或指导
makeExecutableSchema
仍然是 graphql-tools
的一部分,您可以继续使用它,如文档中 here 所示。文档中显示的示例的问题在于它不等同于您之前所做的。您应该使用 loadTypedefsSync
代替:
import { loadTypedefsSync } from '@graphql-tools/load';
import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader';
import { addResolversToSchema } from '@graphql-tools/schema';
const sources = loadTypedefsSync(join(__dirname, 'schema.graphql'), { loaders: [new GraphQLFileLoader()] });
const documentNodes = sources.map(source => source.document);
const resolvers = { Query: {...} };
const schema = makeExecutableSchema({ typeDefs, resolvers });
或者,如果您采用 loadSchema
路线,您应该能够在加载模式后将指令应用于您的模式:
import { SchemaDirectiveVisitor } from "@graphql-tools/utils";
import { loadSchemaSync } from '@graphql-tools/load';
import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader';
import { addResolversToSchema } from '@graphql-tools/schema';
const schema = loadSchemaSync(join(__dirname, 'schema.graphql'), { loaders: [new GraphQLFileLoader()] });
const resolvers = { Query: {...} };
const schemaWithResolvers = addResolversToSchema({
schema,
resolvers,
});
SchemaDirectiveVisitor.visitSchemaDirectives(schemaWithResolvers, schemaDirectives);
我试过这种方法,但无法解决问题。采用以下方法的独特解决方案:
const { ApolloServer, makeExecutableSchema, gql} = require('apollo-server-express')
const { loadTypedefsSync } = require('@graphql-tools/load')
const { GraphQLFileLoader } = require('@graphql-tools/graphql-file-loader')
const path = require('path')
const sources = loadTypedefsSync(
path.resolve(__dirname, '../schema/root.graphql'),
{ loaders: [new GraphQLFileLoader()] }
)
const typeDefs = sources.map(source => source.document)
const schema = makeExecutableSchema({
typeDefs: gql`${typeDefs[0]}`,
resolvers,
})
我遇到了同样的问题,我通过 .graphql
加载了架构,我想添加 graphql-constraint-directive。我的解决方案是使用 loadSchemaSync
加载模式,然后使用 wrapSchema
来使用转换函数,您还需要将指令添加到您的 .graphql
文件之一:
import { addResolversToSchema, wrapSchema } from 'graphql-tools';
import { GraphQLSchema } from 'graphql';
import resolvers from './resolver';
schema = loadSchemaSync('./**/*.graphql', {
loaders: [new GraphQLFileLoader()],
});
const schemaWithResolver = addResolversToSchema({
schema,
resolvers
});
const { constraintDirective } = require('graphql-constraint-directive')
const schemaConstrain = wrapSchema({
schema: schemaWithResolver,
transforms: [constraintDirective()]
})
我的困境开始于一个简单的愿望,即想将我的 graphql 模式从单个 .graphql 文件扩展到多个文件,这样我就可以更好地组织模式,这样它就不会增长到一个失控的大文件。
我的原始布局非常简单,我在 schema.graphql
文件中有一个工作模式。我可以使用 graphql-import 库中的 importSchema('server/schema.graphql')
将其解析为字符串,该库现已弃用 https://github.com/ardatan/graphql-import
他们提到它已在最新版本中合并到 graphql-tools
并在此处提供迁移教程 https://www.graphql-tools.com/docs/migration-from-import 该教程看起来非常简单,因为他们的第一个示例几乎准确地说明了我的代码看起来像(除了我不使用 es6 导入但老式的要求):
import { importSchema } from 'graphql-import';
import { makeExecutableSchema } from 'graphql-tools';
const typeDefs = importSchema(join(__dirname, 'schema.graphql'));
const resolvers = {
Query: {...}
};
const schema = makeExecutableSchema({ typeDefs, resolvers });
然后他们说要修改它,只需进行这些更改
import { loadSchemaSync } from '@graphql-tools/load';
import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader';
import { addResolversToSchema } from '@graphql-tools/schema';
const schema = loadSchemaSync(join(__dirname, 'schema.graphql'), { loaders: [new GraphQLFileLoader()] });
const resolvers = { Query: {...} };
const schemaWithResolvers = addResolversToSchema({
schema,
resolvers,
});
我做了这些更改,但重要的区别是他们不再在他们的示例中使用 makeExecutableSchema()
,这对我来说非常重要,因为我需要包含指令。我现在如何处理架构?我如何声明指令?他们的指令文档仍然使用 makeExecutableSchema
但我不能再使用它了,因为新的 loadSchemaSync
函数 returns 一个对象而不是我需要传递给 typeDefs
的字符串文字在 makeExecutableSchema
我正在使用 apollo-server,所以似乎一个可能的解决方法是在 apollo-server 构造函数中声明指令,然后将这个新的 schemaWithResolvers
作为模式传入
const server = new ApolloServer({
schema, //this includes now the returned value of using addResolversToSchema()
schemaDirectives : {
auth:AuthDirective,
authRole: AuthRoleDirective
}
context : ({req}) => //dostuff,
});
这允许我的服务器 运行,并且我可以执行查询和更改,但是,我的指令不再有效,并且我不再对受保护的查询进行身份验证。
我想要一种方法来导入我的 .graphql 文件并将其解析为一个字符串,这样我就可以在 typeDefs
中使用它,就像我以前使用 importSchema() 一样,或者一种不使用 importSchema() 来声明我的目录的方法makeExecutableSchema() 以便他们再次继续工作!
我查阅了文档并查看了其他库,但到目前为止我一直在做空,非常感谢任何提示或指导
makeExecutableSchema
仍然是 graphql-tools
的一部分,您可以继续使用它,如文档中 here 所示。文档中显示的示例的问题在于它不等同于您之前所做的。您应该使用 loadTypedefsSync
代替:
import { loadTypedefsSync } from '@graphql-tools/load';
import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader';
import { addResolversToSchema } from '@graphql-tools/schema';
const sources = loadTypedefsSync(join(__dirname, 'schema.graphql'), { loaders: [new GraphQLFileLoader()] });
const documentNodes = sources.map(source => source.document);
const resolvers = { Query: {...} };
const schema = makeExecutableSchema({ typeDefs, resolvers });
或者,如果您采用 loadSchema
路线,您应该能够在加载模式后将指令应用于您的模式:
import { SchemaDirectiveVisitor } from "@graphql-tools/utils";
import { loadSchemaSync } from '@graphql-tools/load';
import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader';
import { addResolversToSchema } from '@graphql-tools/schema';
const schema = loadSchemaSync(join(__dirname, 'schema.graphql'), { loaders: [new GraphQLFileLoader()] });
const resolvers = { Query: {...} };
const schemaWithResolvers = addResolversToSchema({
schema,
resolvers,
});
SchemaDirectiveVisitor.visitSchemaDirectives(schemaWithResolvers, schemaDirectives);
我试过这种方法,但无法解决问题。采用以下方法的独特解决方案:
const { ApolloServer, makeExecutableSchema, gql} = require('apollo-server-express')
const { loadTypedefsSync } = require('@graphql-tools/load')
const { GraphQLFileLoader } = require('@graphql-tools/graphql-file-loader')
const path = require('path')
const sources = loadTypedefsSync(
path.resolve(__dirname, '../schema/root.graphql'),
{ loaders: [new GraphQLFileLoader()] }
)
const typeDefs = sources.map(source => source.document)
const schema = makeExecutableSchema({
typeDefs: gql`${typeDefs[0]}`,
resolvers,
})
我遇到了同样的问题,我通过 .graphql
加载了架构,我想添加 graphql-constraint-directive。我的解决方案是使用 loadSchemaSync
加载模式,然后使用 wrapSchema
来使用转换函数,您还需要将指令添加到您的 .graphql
文件之一:
import { addResolversToSchema, wrapSchema } from 'graphql-tools';
import { GraphQLSchema } from 'graphql';
import resolvers from './resolver';
schema = loadSchemaSync('./**/*.graphql', {
loaders: [new GraphQLFileLoader()],
});
const schemaWithResolver = addResolversToSchema({
schema,
resolvers
});
const { constraintDirective } = require('graphql-constraint-directive')
const schemaConstrain = wrapSchema({
schema: schemaWithResolver,
transforms: [constraintDirective()]
})