Циклическая схема выдает ошибку «Ошибка: схема должна содержать уникальные именованные типы, но содержит несколько типов с именем« Узел ».» - PullRequest
0 голосов
/ 22 октября 2018

Я новичок в GraphQL с использованием nodejs.Я застрял в двунаправленном отображении схемы.посты <-> авторов.Использование graphql и graphql-relay module.

Ниже приведены две схемы, которые мы используем.

--posts.js // here we are requiring authors.js 
const {
    AuthorType,
    schema: AuthorSchema,
    AuthorsConnection
} = require('./authors');

class Post {}

const {
    nodeInterface,
    nodeField
} = nodeDefinitions(
    globalId => {
        const {
            type,
            id
        } = fromGlobalId(globalId);
        // return based on the id
        return DataSource['posts'][0];
    },
    obj => {
        console.log(" : PostType : ", PostType);
        // type to be return 
        return Post;
    }
);

const PostType = new GraphQLObjectType({
    "name": "PostType",
    "description": "Posts type and it's relevant fields",
    "fields": () => ({
        "id": globalIdField('Post'),
        "title": {
            "type": GraphQLString
        },
        "body": {
            "type": GraphQLString
        },
        "author": {
            "type": AuthorsConnection,
            "resolve": (parent, argument, root, currentSdl) => {
                console.log("v1, v2, v3, v4  :", parent);
                if (parent.author)
                    return connectionFromArray(DataSource['authors'], {})
                return [];
            }
        }
    }),
    isTypeOf: Post,
    interfaces: [nodeInterface]
});

const {
    connectionType: PostsConnection,
    edgeType: GQLPostEdge
} = connectionDefinitions({
    name: "Post",
    nodeType: PostType
});
module.exports = exports = {
    PostType,
    PostsConnection,
    schema: {
        post: nodeField,
        posts: {
            type: PostsConnection,
            resolve: (root, v2, v3) => {
                return connectionFromArray(DataSource['posts'], {});
            }
        }
    }
};

--authors.js // here we have required posts.js

const {
    PostType,
    PostsConnection
} = require('./posts');

class Author {}

const {
    nodeInterface,
    nodeField
} = nodeDefinitions(
    globalId => {
        const {
            type,
            id
        } = fromGlobalId(globalId);
        // return based on the id
        return DataSource['authors'][0];
    },
    obj => {
        console.log(" : Authorype : ", Authorype);
        // type to be return 
        return Author;
    }
);

const AuthorType = new GraphQLObjectType({
    "name": "AuthorType",
    "description": "Author type and it's relevant fields",
    "fields": () => ({
        "id": globalIdField('Author'),
        "firstName": {
            "type": GraphQLString
        },
        "lastName": {
            "type": GraphQLString
        },
        authorPosts: {
            type: PostsConnection,
            resolve: (parent, args, root, context) => {
                return connectionFromArray(DataSource['posts'], {});
            }
        }
    }),
    isTypeOf: null,
    interfaces: [nodeInterface]
});

const {
    connectionType: AuthorsConnection,
    edgeType: GQLAuthorEdge
} = connectionDefinitions({
    name: "Author",
    nodeType: AuthorType
});

module.exports = exports = {
    AuthorType,
    AuthorsConnection,
    schema: {
        author: nodeField,
        authors: {
            type: AuthorsConnection,
            resolve: (root, v2, v3) => {
                return connectionFromArray(DataSource['authors'], {});
            }
        }
    }
};

Как только я объединю схему выше дляGraphQL Я получаю следующее сообщение об ошибке.

Error: Schema must contain unique named types but contains multiple types named "Node".

Я пытался отладить эту проблему, я наблюдаю следующее.

  • Как только я изменяю поле "авторы" из схемы сообщений на другоечем «AuthorsConnection» он начинает работать.
  • Или, если удалить поле "авторы" из схемы сообщений, оно начинает работать.

Пожалуйста, дайте мне знать, в чем здесь проблема, имеет ли это отношение к nodeDefinitions функции?

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Вместе с ответом выше, данным @Benjie.Я нашел способ преодоления проблем, которые привели к ошибке Error: Schema must contain unique named types but contains multiple types named "Node"..

Ниже приведены ключевые моменты, которые необходимо проверить, когда мы выполняем graphql модульным способом.

  • Не создавайте новые экземпляры типа, например: const PostType = new GraphQLObjectType({}) он должен всегда отправлять один объект, а не новый объект каждый раз.
  • использовать nodeDefinations только один раз.
  • Проверить наличиециклические проблемы в общей проблеме JavaScript, которая будет происходить.

Спасибо.

0 голосов
/ 22 октября 2018

Это действительно связано с функцией nodeDefinitions.Из graphql-relay документов:

nodeDefinitions возвращает интерфейс Node, который могут быть реализованы объектами, и возвращает корневое поле node для включения в тип запроса.Чтобы реализовать это, требуется функция для разрешения идентификатора объекта и для определения типа данного объекта.

Вы вызываете это дважды, что приводит к Nodeтип определяется дважды, и вы ссылаетесь на один из них:

schema: {
    post: nodeField,

// ...

schema: {
    author: nodeField,

Это вызывает ошибку - теперь есть два независимых экземпляра Node, которые недопустимы.

Решениеэто только один раз вызвать nodeDefinitions, а затем передать ссылку на сгенерированные nodeField и nodeInterface в соответствующие места.Тогда вашей функции globalId => {...} нужно будет взглянуть на type, чтобы выяснить, как получить соответствующую запись, будь то автор или сообщение.

...