Cyclic schema giving error as "Error: Schema must contain unique named types but contains multiple types named "Node"."
Cyclic schema giving error as "Error: Schema must contain unique named types but contains multiple types named "Node"."
我是 'GraphQL' 使用 nodejs 的新手。我被困在双向模式映射中。帖子 <-> 作者。使用 graphql and 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".
我试着调试了这个问题,下面是我观察到的。
- 一旦我将 "authors" 字段从帖子模式更改为非
"AuthorsConnection" 它开始工作了。
- 或者如果移除 "authors" 字段
从帖子模式开始工作。
请告诉我这里有什么问题,它与 nodeDefinitions
功能有关吗?
确实与nodeDefinitions
功能有关。来自 graphql-relay
文档:
nodeDefinitions
returns the Node
interface that objects can implement, and returns the node
root field to include on the query type. To implement this, it takes a function to resolve an ID to an object, and to determine the type of a given object.
您调用了两次,这导致 Node
类型被定义了两次,并且您引用了每个类型之一:
schema: {
post: nodeField,
// ...
schema: {
author: nodeField,
这是导致错误的原因 - 现在有两个无效的 Node
实例。
解决方法是只调用一次nodeDefinitions
,然后将生成的nodeField
和nodeInterface
的引用传到相关的地方。然后你的 globalId => {...}
函数将需要查看 type
来弄清楚如何获取相关记录,无论是作者还是 post.
以及@Benjie 给出的上述答案。我找到了解决导致 Error: Schema must contain unique named types but contains multiple types named "Node".
.
错误的方法
以下是我们在以模块化方式制作graphql时需要检查的关键点。
- 不要创建类型的新实例,例如:
const PostType = new GraphQLObjectType({})
它应该始终发送单个对象而不是每次都发送新对象。
- 仅使用
nodeDefinations
一次。
- 检查常见的循环问题 javascript 会发生的问题。
谢谢。
我是 'GraphQL' 使用 nodejs 的新手。我被困在双向模式映射中。帖子 <-> 作者。使用 graphql and 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".
我试着调试了这个问题,下面是我观察到的。
- 一旦我将 "authors" 字段从帖子模式更改为非 "AuthorsConnection" 它开始工作了。
- 或者如果移除 "authors" 字段 从帖子模式开始工作。
请告诉我这里有什么问题,它与 nodeDefinitions
功能有关吗?
确实与nodeDefinitions
功能有关。来自 graphql-relay
文档:
nodeDefinitions
returns theNode
interface that objects can implement, and returns thenode
root field to include on the query type. To implement this, it takes a function to resolve an ID to an object, and to determine the type of a given object.
您调用了两次,这导致 Node
类型被定义了两次,并且您引用了每个类型之一:
schema: {
post: nodeField,
// ...
schema: {
author: nodeField,
这是导致错误的原因 - 现在有两个无效的 Node
实例。
解决方法是只调用一次nodeDefinitions
,然后将生成的nodeField
和nodeInterface
的引用传到相关的地方。然后你的 globalId => {...}
函数将需要查看 type
来弄清楚如何获取相关记录,无论是作者还是 post.
以及@Benjie 给出的上述答案。我找到了解决导致 Error: Schema must contain unique named types but contains multiple types named "Node".
.
以下是我们在以模块化方式制作graphql时需要检查的关键点。
- 不要创建类型的新实例,例如:
const PostType = new GraphQLObjectType({})
它应该始终发送单个对象而不是每次都发送新对象。 - 仅使用
nodeDefinations
一次。 - 检查常见的循环问题 javascript 会发生的问题。
谢谢。