6

我的困境始于将我的 graphql 模式从单个 .graphql 文件扩展到多个文件的简单愿望,这样我就可以更好地组织模式,因此它不会发展成一个失控的巨大文件。

我的原始布局非常简单,我在schema.graphql文件中有一个工作模式。我将能够使用importSchema('server/schema.graphql')graphql-import 库将其解析为字符串,该库现已弃用https://github.com/ardatan/graphql-import

他们提到它已合并到graphql-tools最新版本中并在此处提供迁移教程https://www.graphql-tools.com/docs/migration-from-import该教程似乎非常简单,因为他们的第一个示例几乎说明了正是我的代码的样子(除了我不使用 es6 import 但老式要求):

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函数返回一个对象而不是我需要传递给的字符串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() 一样在内部使用它,或者在不使用 makeExecutableSchema() 的情况下声明我的指令,以便它们继续工作!

我已经浏览了文档并查看了其他库,到目前为止我一直很短,非常感谢任何提示或指导

4

3 回答 3

4

makeExecutableSchema仍然是其中的一部分,graphql-tools您可以继续使用它,如文档中所示。文档中显示的示例的问题在于它不等同于您之前所做的。您应该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);
于 2020-06-18T10:57:17.170 回答
2

我尝试过这种方式,但我无法解决问题。一个独特的解决方案设法采取了以下方法:

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,
})
于 2020-07-05T23:23:35.977 回答
0

我有同样的问题,我通过加载架构.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()]
})

Schema Wrapping 文档

于 2021-04-28T12:52:59.393 回答