GraphQL 在执行期间是不是曾经冗余地访问字段?
Posted
技术标签:
【中文标题】GraphQL 在执行期间是不是曾经冗余地访问字段?【英文标题】:Does GraphQL ever redundantly visit fields during execution?GraphQL 在执行期间是否曾经冗余地访问字段? 【发布时间】:2019-12-04 21:30:01 【问题描述】:我正在阅读this 文章,它使用了以下查询:
getAuthor(id: 5)
name
posts
title
author
name # this will be the same as the name above
它被解析并变成了一个 AST,如下所示:
显然它带回了冗余信息(作者的名字被问了两次),所以我想知道 GraphQL 是如何处理这些的。它是否冗余地获取该信息?该图是对实际 AST 的正确描述吗?
如果您能深入了解与此相关的查询解析和执行过程,我们将不胜感激,谢谢。
编辑:我知道这可能会因 GraphQl 服务器的实际实现而异,但我想知道标准/最佳实践是什么。
【问题讨论】:
【参考方案1】:是的,在这种情况下,GraphQL 可能会多次获取相同的信息。 GraphQL 不会记忆解析器函数,因此即使使用相同的参数和相同的父值调用它,它仍然会再次运行。
在 GraphQL 中使用数据库时,这是一个相当常见的问题。最常见的解决方案是使用DataLoader,它不仅可以批处理您的数据库请求,还可以在 GraphQL 请求期间为这些请求提供缓存。这样,即使多次请求特定记录,也只会从数据库中获取一次。
另一种方法(虽然更复杂)是根据在根级别执行的请求字段组合单个数据库查询。例如,getAuthor
的解析器可以构造一个查询,该查询将返回作者、他们的帖子以及该帖子的每个作者。使用这种方法,我们可以跳过为Author
类型上的posts
字段或Post
类型上的author
字段编写解析器,而只使用默认解析器行为。但是,为了做到这一点并避免过度获取,我们必须在 getAuthor
解析器中解析 GraphQL 请求,以确定请求了哪些字段,因此应该将其包含在我们的数据库查询中。
【讨论】:
感谢您的回复。当您说“根据在根级别执行的请求字段组合单个数据库查询”时,我假设您的意思是我们必须解析查询并以不同方式构造 AST 以避免冗余节点?是否有任何 GraphQL 客户端这样做? 对不起,这不是我的意思。我本来可以更清楚的。您不会避免冗余节点,您只需使用单个数据库查询来捕获所有相关节点。我编辑了我的答案以详细说明。 感谢您的澄清!以上是关于GraphQL 在执行期间是不是曾经冗余地访问字段?的主要内容,如果未能解决你的问题,请参考以下文章
Apollo GraphQL - 是不是可以执行请求不同字段的相同查询?
使用 this.props.relay.setVariables 时,Relay/Graphql 查询字段“node”而不是“viewer”