简体   繁体   English

循环模式给出错误为“错误:模式必须包含唯一的命名类型,但包含多个名为“节点”的类型。

[英]Cyclic schema giving error as "Error: Schema must contain unique named types but contains multiple types named "Node"."

I am new to 'GraphQL' using nodejs.我是使用 nodejs 的“GraphQL”新手。 I am stucked into bi-directional schema mapping.我被困在双向模式映射中。 posts <-> authors.帖子 <-> 作者。 Using graphql and graphql-relay module.使用graphqlgraphql-relay模块。

Following are the two schema we are using.以下是我们正在使用的两个模式。

--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'], {});
            }
        }
    }
};

Once I merge above schema for GraphQL I am getting following error.一旦我为 GraphQL 合并上述模式,我就会收到以下错误。

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

I tried to debugged this issue, following is I observed following.我试图调试这个问题,以下是我观察到的。

  • Once I change "authors" field from posts schema to other than "AuthorsConnection" it starts working.一旦我将“作者”字段从帖子模式更改为“AuthorsConnection”以外的其他字段,它就会开始工作。
  • Or if removed "authors" field from posts schema it starts working.或者,如果从帖子架构中删除“作者”字段,它就会开始工作。

Please let me know what is issue here, is it relevant to nodeDefinitions function?请让我知道这里有什么问题,它与nodeDefinitions功能有关吗?

It is indeed related to the nodeDefinitions function.它确实与nodeDefinitions函数有关。 From the graphql-relay docs:来自graphql-relay文档:

nodeDefinitions returns the Node interface that objects can implement, and returns the node root field to include on the query type. nodeDefinitions返回对象可以实现的Node接口,并返回要包含在查询类型中的node根字段。 To implement this, it takes a function to resolve an ID to an object, and to determine the type of a given object.为了实现这一点,需要一个函数来将 ID 解析为一个对象,并确定给定对象的类型。

You're calling this twice, which is resulting in the Node type being defined twice, and you're referencing one of each:您调用了两次,这导致Node类型被定义两次,并且您引用了其中的一个:

schema: {
    post: nodeField,

// ...

schema: {
    author: nodeField,

This is causing the error - there's now two independent instances of Node which is invalid.这导致了错误 - 现在有两个独立的Node实例无效。

The solution is to only call nodeDefinitions once, and then pass the reference to the generated nodeField and nodeInterface to the relevant places.解决办法是只调用一次nodeDefinitions ,然后将生成的nodeFieldnodeInterface的引用传到相关的地方。 Then your globalId => {...} function will need to look at the type to figure out how to get the relevant record, be it an author or a post.然后您的globalId => {...}函数将需要查看type以找出如何获取相关记录,无论是作者还是帖子。

Along with above answer given by @Benjie.连同@Benjie给出的上述答案。 I find out the way to overcome issues which was resulting into error of Error: Schema must contain unique named types but contains multiple types named "Node".我找到了解决导致错误的问题的方法Error: Schema must contain unique named types but contains multiple types named "Node". . .

Following are the key points to be check when we are making graphql in modular way.以下是我们以模块化方式制作 graphql 时要检查的关键点。

  • Don't create new instances of type, For eg: const PostType = new GraphQLObjectType({}) it should always send single object rather than new object every time.不要创建新的类型实例,例如: const PostType = new GraphQLObjectType({})它应该总是发送单个对象而不是每次都发送新对象。
  • use nodeDefinations only once.仅使用nodeDefinations一次。
  • Check for the cyclic issues in common javascript issue which will occurs.检查将发生的常见 javascript 问题中的循环问题。

Thanks.谢谢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 Express GraphQL 中出错:架构必须包含唯一命名的类型,但包含多个名为“String”的类型 - Getting error in Express GraphQL: Schema must contain uniquely named types but contains multiple types named "String" 错误:架构必须包含唯一命名的类型,但包含多个名为“DateTime”的类型 - Error: Schema must contain uniquely named types but contains multiple types named "DateTime" 在 Apollo Express GraphQL 中出现错误:错误:模式必须包含唯一命名的类型,但包含多个名为“DateTime”的类型 - Getting error in Apollo Express GraphQL: Error: Schema must contain uniquely named types but contains multiple types named "DateTime" Avro 架构定义在传递两种可能的类型 Node.JS 时抛出无效值类型错误 - Avro Schema Definition Throwing Invalid Value Type Error When Passing Two Possible Types Node.JS 错误:提供的用于构建架构的类型之一缺少名称 - Error: One of the provided types for building the Schema is missing a name mongoose自定义模式类型 - mongoose custom schema types 自定义 Keystonejs 服务器端函数:“没有名为‘public’的可执行架构”错误 - Custom Keystonejs server-side functions: "No executable schema named 'public'" error Schema.Types.ObjectId未定义 - Schema.Types.ObjectId undefined 具有2个(或更多)模式类型的猫鼬数组 - mongoose array with 2 (or more) schema types 修复节点js中已定义架构的验证错误 - Fixing validation error for defined schema in node js
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM