Проблемы с переходом с graphql-import на только graphql-tools с ApolloServer, директивы перестают работать - PullRequest
2 голосов
/ 18 июня 2020

Мое положение началось с простого желания расширить мою схему 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, но старый fashoined требует ):

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 (), чтобы они продолжали работать снова!

Я просматривал документацию и видел другие библиотеки, и до сих пор я не останавливаюсь, любые советы или рекомендации приветствуются

Ответы [ 2 ]

2 голосов
/ 18 июня 2020

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 });

В качестве альтернативы, если вы go маршрут 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);
0 голосов
/ 06 июля 2020

Я пробовал этот способ, но не смог решить проблему. Уникальное решение, в котором реализован следующий подход:

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,
})
...