2

我是使用 nodejs 的“GraphQL”新手。我被困在双向模式映射中。帖子 <-> 作者。使用graphqlgraphql-relay模块。

以下是我们正在使用的两个模式。

--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功能有关吗?

4

2 回答 2

1

确实和nodeDefinitions功能有关。从graphql-relay文档:

nodeDefinitions返回Node对象可以实现的接口,并返回node要包含在查询类型中的根字段。为了实现这一点,它需要一个函数来将 ID 解析为对象,并确定给定对象的类型。

您调用了两次,这导致Node类型被定义了两次,并且您引用了其中一个:

schema: {
    post: nodeField,

// ...

schema: {
    author: nodeField,

这导致了错误 - 现在有两个独立的实例Node无效。

解决方案是只调用nodeDefinitions一次,然后将引用传递给生成的nodeFieldnodeInterface相关的地方。然后您的globalId => {...}函数将需要查看type以找出如何获取相关记录,无论是作者还是帖子。

于 2018-10-22T14:27:51.953 回答
0

连同@Benjie 给出的上述答案。我找到了克服导致错误的问题的方法Error: Schema must contain unique named types but contains multiple types named "Node".

以下是我们以模块化方式制作graphql时要检查的关键点。

  • 不要创建类型的新实例,例如:const PostType = new GraphQLObjectType({})它应该始终发送单个对象而不是每次都发送新对象。
  • 只使用nodeDefinations一次。
  • 检查将发生的常见javascript问题中的循环问题。

谢谢。

于 2018-10-24T12:29:41.540 回答