我想澄清一下我应该在Apollo + GraphQL中使用哪种方法来解析我的解析器函数
让我们假设以下架构:
type Post {
id: Int
text: String
upVotes: Int
}
type Author{
name: String
posts: [Post]
}
schema {
query: Author
}
ApoloGraphql tutorial建议使用这样的解析图:
{Query:{
author(_, args) {
return author.findAll()
}
}
},
Author {
posts: (author) => author.getPosts(),
}
据我所知,关于帖子的每一个逻辑,例如必须使用get author with posts where the count of post upVotes > args.upVotes
方法处理author
。这给了我们以下解析图:
{Query:{
author(_, args) {
return author.findAll({
include:[model: Post]
where: {//post upVotes > args.upVotes}
})
}
},
Author {
posts: (author) => author.getPosts(),
}
致电author
,首先会选择包含一个已加入查询中帖子的作者,其中的帖子大于args.upVotes
。然后,由于Author ... getPosts()
从技术上讲,我可以通过删除Author
来获得相同的结果,因为帖子已包含在小author
方法中。
我有以下问题:
我需要这个声明吗?在哪些情况下?
Author {
posts: (author) => author.getPosts(),
}
如果不是,那么如何确定是否请求了帖子字段 我可以有条不紊地发布帖子,这不仅取决于 参数,但也在请求的字段上?
如果是,哪些帖子将包含最终结果?来自的帖子 include语句,或getPosts()?
答案 0 :(得分:1)
您在问题中包含的解析图无效。我会假设你对Author
类型的意思是这样的:
Author {
posts: (author) => author.getPosts(),
}
只要您的author
查询总是解析为包含posts
属性的对象数组,那么您就会认为它没有&#39 ;在posts
类型的Author
字段中包含客户解析程序是有意义的。在这种情况下,您的查询解析程序已经填充了所有必填字段,我们不必做任何其他操作。
GraphQL使用默认解析程序,该解析程序在向下传递给解析程序的父(或根)对象上查找属性,并在它们与要解析的字段的名称匹配时使用这些属性。因此,如果GraphQL正在解析posts
字段,并且posts
没有解析器,则默认情况下它会查看它正在处理的Author
对象,如果有它的名称为posts
,它将该字段解析为其值。
当我们提供自定义解析程序时,该解析程序会覆盖默认行为。因此,如果您的解析器是,例如:
posts: () => []
然后GraphQL总会返回一组空的帖子,即使author.findAll()
返回的对象包含帖子。
那么您何时需要为posts
添加解析器?
如果您的author
解析器没有"包含"帖子,但客户要求该字段。就像你说的那样,问题是我们在某些情况下可能会进行不必要的额外通话,具体取决于你的author
解析器"包括"这些帖子与否。你可以通过做这样的事情来解决这个问题:
posts: (author) => {
if (author.posts) return author.posts
return author.getPosts()
}
// or more succinctly
posts: author => author.posts ? author.posts : author.getPosts()
这样,如果我们确实需要获取帖子,我们只会调用getPosts
。或者,您可以省略posts
解析程序并在author
解析程序中处理此问题。我们可以查看传递给解析器的第四个参数,以获取有关请求的信息,包括请求的字段。例如,你的解析器看起来像这样:
author: (root, args, context, info) => {
const include = []
const requestedPosts = info.fieldNodes[0].selectionSet.selections.includes(s => s.name.value === 'posts'
if (requestedPosts) include.push(Post)
return Author.findAll({include})
}
现在,如果客户特别要求,您的解析器将仅包含每位作者的帖子。提供给解析器的AST树对象很难解析,但是有一些库(如this one)可以帮助解决这个问题。