循环模式给出错误为“错误:模式必须包含唯一的命名类型,但包含多个名为“节点”的类型。”
Posted
技术标签:
【中文标题】循环模式给出错误为“错误:模式必须包含唯一的命名类型,但包含多个名为“节点”的类型。”【英文标题】:Cyclic schema giving error as "Error: Schema must contain unique named types but contains multiple types named "Node"." 【发布时间】:2019-03-26 15:29:20 【问题描述】:我是使用 nodejs 的“GraphQL”新手。我被困在双向模式映射中。帖子 作者。使用graphql 和graphql-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
功能有关吗?
【问题讨论】:
【参考方案1】:确实和nodeDefinitions
函数有关。来自graphql-relay
文档:
nodeDefinitions
返回对象可以实现的Node
接口,并返回node
根字段以包含在查询类型中。为了实现这一点,它需要一个函数来将 ID 解析为对象,并确定给定对象的类型。
您调用了两次,这导致 Node
类型被定义了两次,并且您引用了每个:
schema:
post: nodeField,
// ...
schema:
author: nodeField,
这是导致错误的原因 - 现在有两个无效的 Node
独立实例。
解决方法是只调用一次nodeDefinitions
,然后将生成的nodeField
和nodeInterface
的引用传递给相关的地方。然后您的globalId => ...
函数将需要查看type
以了解如何获取相关记录,无论是作者还是帖子。
【讨论】:
您好本杰,感谢您的快速回复。只调用一次“nodeDefinitions”就可以了。但是对于大号来说是否可行。要从单个位置获取的类型(如帖子、作者等)。还有其他模块化的方法吗? fetcher 只是一个函数;并从 fromGlobalId 你得到一个类型;那么您可以使用它来查看任意地图并调用相关的提取器(如果存在);所以每种类型都可以在 fetcher map 上注册一个 fetcher 函数。这只是一种方法。【参考方案2】:连同@Benjie 给出的上述答案。我找到了克服导致Error: Schema must contain unique named types but contains multiple types named "Node".
错误的问题的方法。
以下是我们以模块化方式制作graphql时需要检查的关键点。
不要创建类型的新实例,例如:const PostType = new GraphQLObjectType()
它应该始终发送单个对象而不是每次都发送新对象。
只使用一次nodeDefinations
。
检查常见的javascript issue中会出现的循环问题。
谢谢。
【讨论】:
以上是关于循环模式给出错误为“错误:模式必须包含唯一的命名类型,但包含多个名为“节点”的类型。”的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 在 spatie-permission 的 foreach 循环中给出错误
ses.sendmail() 给出 CORS 错误。响应中的“Access-Control-Allow-Origin”标头不得为通配符“*”。凭证模式为“包含”