[英]How to nest two graphQL queries in a schema?
I've created a GraphQLSchema with two fields, both using a resolve()
to get the data from a mongoDB. 我创建了一个包含两个字段的GraphQLSchema ,它们都使用
resolve()
从mongoDB获取数据。
With that, the query... 有了它,查询......
{
article(id: "Dn59y87PGhkJXpaiZ") {
title
},
articleContent(id: "Dn59y87PGhkJXpaiZ") {
_id,
content(language: "en"),
type
}
}
...results in: ...结果是:
{
"data": {
"article": {
"title": "Sample Article"
},
"articleContent": [
{
"_id": "Kho2N8yip3uWj7Cib",
"content": "group",
"type": "group"
},
{
"_id": "mFopAj4jQQuGAJoAH",
"content": "paragraph",
"type": null
}
]
}
}
But I need a result structure like this (content should be inside of article object): 但我需要这样的结果结构(内容应该在文章对象内):
Expected result 预期结果
{
"data": {
"article": {
"title": "Sample Article",
"content": [
{
"_id": "Kho2N8yip3uWj7Cib",
"content": "group",
"type": "group"
},
{
"_id": "mFopAj4jQQuGAJoAH",
"content": "paragraph",
"type": null
}
]
},
}
}
For me the problem are both async mongoDB resolves in my schema: 对我来说,问题是异步mongoDB在我的架构中解析:
export default new GraphQLSchema({
query: new GraphQLObjectType({
name: 'RootQueryType',
fields: {
article: {
type: new GraphQLObjectType({
name: 'article',
fields: {
title: {
type: GraphQLString,
resolve (parent) {
return parent.title
}
}
}
}),
args: {
id: { type: new GraphQLNonNull(GraphQLID) }
},
async resolve ({ db }, { id }) {
return db.collection('content').findOne({ _id: id })
}
},
articleContent: {
type: new GraphQLList(new GraphQLObjectType({
name: 'articleContent',
fields: {
_id: { type: GraphQLID },
type: { type: GraphQLString },
content: {
type: GraphQLString,
args: {
language: { type: new GraphQLNonNull(GraphQLString) }
},
resolve (parent, { language }, context) {
return parent.content[language][0].content
}
}
}
})),
args: {
id: { type: new GraphQLNonNull(GraphQLID) }
},
async resolve ({ db }, { id }) {
return db.collection('content').find({ main: id }).toArray()
}
}
}
})
})
Update 更新
If I nest the content inside the article, I do get the error Cannot read property 'collection' of undefined
如果我在文章中嵌入内容,我确实得到错误
Cannot read property 'collection' of undefined
export default new GraphQLSchema({
query: new GraphQLObjectType({
name: 'RootQueryType',
fields: {
article: {
type: new GraphQLObjectType({
name: 'article',
fields: {
title: {
type: GraphQLString,
resolve (parent) {
return parent.title
}
},
articleContent: {
type: new GraphQLList(new GraphQLObjectType({
name: 'articleContent',
fields: {
_id: { type: GraphQLID },
type: { type: GraphQLString },
content: {
type: GraphQLString,
args: {
language: { type: new GraphQLNonNull(GraphQLString) }
},
resolve (parent, { language }, context) {
return parent.content[language][0].content
}
}
}
})),
args: {
id: { type: new GraphQLNonNull(GraphQLID) }
},
async resolve ({ db }, { id }) { // db is undefined here!!
return db.collection('content').find({ main: id }).toArray()
}
}
}
}),
args: {
id: { type: new GraphQLNonNull(GraphQLID) }
},
async resolve ({ db }, { id }) {
return db.collection('content').findOne({ _id: id })
}
}
}
})
})
First, let's analyze the signature of a resolver. 首先,让我们分析解析器的签名。
function resolve(root, args, context)
root
is the value returned by the parent resolver. root
是父解析器返回的值。 This is why you get Cannot read property 'collection' of undefined
because the parent resolver didn't return an object with a db
property. 这就是你
Cannot read property 'collection' of undefined
原因,因为父解析器没有返回带有db
属性的对象。
args
are the argument passed to the field, like so: article(id:'someid')
when writing the query. args
是传递给字段的参数,如下所示: article(id:'someid')
在编写查询时。
context
is a parameter that is passed to every resolver, and is mostly used to make accessible API-wide utilities, like your db
connection. context
是传递给每个解析程序的参数,主要用于创建可访问的API范围的实用程序,例如db
连接。
To have db
set inside your context, you can initialize your GraphQL server with it. 要在上下文中设置
db
,可以使用它初始化GraphQL服务器。
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: root,
context: {
db: db
},
graphiql: true,
}));
About the nesting now, you could have something like this. 关于嵌套现在,你可以有这样的东西。
export default new GraphQLSchema({
query: new GraphQLObjectType({
name: 'RootQueryType',
fields: {
article: {
args: {
id: { type: new GraphQLNonNull(GraphQLID) }
},
resolve (_, { id }) {
return id; // will make it accessible to children resolvers
}
type: new GraphQLObjectType({
name: 'article',
fields: {
title: {
async resolve (id /* resolved by article */, _, { db } /* db from context */) {
const article = await db.collection('content').findOne({ _id: id });
return article.title;
}
type: GraphQLString,
},
content: {
async resolve (id /* resolved by article */, _, { db } /* db from context */) {
const contents = await db.collection('content').find({ main: id }).toArray();
return contents;
}
type: new GraphQLList(new GraphQLObjectType({
name: 'articleContent',
fields: {
_id: { type: GraphQLID },
type: { type: GraphQLString },
content: {
args: {
language: { type: new GraphQLNonNull(GraphQLString) }
},
aync resolve (parent /* resolved in content */, { language }) {
return parent.content[language][0].content
}
type: GraphQLString,
}
}
})),
}
}
}),
}
}
})
})
In order, this will happen: 按顺序,这将发生:
article gets its parameter id and returns it, giving it to children resolvers. article获取其参数id并返回它,将其提供给子解析器。
title and outer content will both fire their request in parallel, accessing the db
in context
. 标题和外部内容将同时触发它们的请求,在
context
访问db
。
when outer content gets back from the db, the inner content field of every element will use their parameter language
to return the right result. 当外部内容从db返回时,每个元素的内部内容字段将使用其参数
language
来返回正确的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.