我是使用nodejs的“ GraphQL”的新手。我陷入了双向模式映射。帖子<->作者。使用graphql和graphql-relay模块。
以下是我们正在使用的两个模式。
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/rounded_corners_background"
android:weightSum="100">
<TableRow
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="40">
<me.grantland.widget.AutofitTextView
android:id="@+id/tvQuestion"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:textSize="40sp"
android:layout_gravity="center"
android:maxLines="1"
app:minTextSize="12sp"
android:paddingBottom="18dp"
android:text="" />
</TableRow>
<TableRow
android:layout_weight="15">
<TextView
android:id="@+id/textViewStableA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:layout_gravity="start"
android:paddingStart="8dp"
android:text="" />
<TextView
android:id="@+id/tvAnswerA"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="100"
android:layout_gravity="start"
android:gravity="center"
android:text="" />
</TableRow>
<TableRow
android:layout_weight="15">
<TextView
android:id="@+id/textViewStableB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="" />
<TextView
android:id="@+id/tvAnswerB"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="100"
android:gravity="center"
android:text="" />
</TableRow>
<TableRow
android:layout_weight="15">
<TextView
android:id="@+id/textViewStableC"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="" />
<TextView
android:id="@+id/tvAnswerC"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="100"
android:gravity="center"
android:text="" />
</TableRow>
<TableRow
android:layout_weight="15">
<TextView
android:id="@+id/textViewStableD"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="" />
<TextView
android:id="@+id/tvAnswerD"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="100"
android:gravity="center"
android:text="" />
</TableRow>
一旦合并了GraphQL的上述架构,我就会遇到以下错误。
--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'], {});
}
}
}
};
我尝试调试此问题,以下是我观察到的以下情况。
请让我知道这里的问题,它与Error: Schema must contain unique named types but contains multiple types named "Node".
函数有关吗?
答案 0 :(得分:1)
它确实与nodeDefinitions
函数有关。来自graphql-relay
文档:
nodeDefinitions
返回对象可以实现的Node
接口,并返回要包含在查询类型中的node
根字段。为此,它需要一个函数来解析对象的ID,并确定给定对象的类型。
您要调用两次,这导致Node
类型被定义两次,并且您要引用其中一种:
schema: {
post: nodeField,
// ...
schema: {
author: nodeField,
这引起了错误-Node
的两个独立实例无效。
解决方案是只调用nodeDefinitions
一次,然后将对生成的nodeField
和nodeInterface
的引用传递到相关位置。然后,您的globalId => {...}
函数将需要查看type
来弄清楚如何获得相关记录,无论是作者还是帖子。
答案 1 :(得分:0)
上面的答案由@Benjie给出。我找到了解决导致Error: Schema must contain unique named types but contains multiple types named "Node".
错误的问题的方法。
以下是我们以模块化方式制作graphql时要检查的关键点。
const PostType = new GraphQLObjectType({})
应该始终发送单个对象,而不是每次都发送新对象。nodeDefinations
一次。谢谢。