GraphQL:一个大查询与大量小查询

Posted

技术标签:

【中文标题】GraphQL:一个大查询与大量小查询【英文标题】:GraphQL: One Big Query vs Lots of Little Queries 【发布时间】:2019-08-12 23:27:30 【问题描述】:

我知道这个问题由来已久——而且它们不是灵丹妙药。但我认为那里可能有一个可靠的模式,我不想发明***。

考虑以下两个架构选项:

方法 1) 我的原始实现

type Query 
  note(id: ID!): Note
  notes(input: NotesQueryInput): [Note!]!

方法 2) 我目前的实验方法

type DatedId 
  date: DateTime!
  id: ID!


type Query 
  note(id: ID!): Note
  notes(input: NotesQueryInput): [DatedId!]!

区别在于:

使用方法 1) notes 查询将返回一个可能较大的 Note 对象列表

使用方法 2)notes 查询将返回更轻的有效负载,但随后将需要执行 n 个额外的查询

所以我的问题是带有内存缓存的 Apollo Client / Server 堆栈,这是最好的方法。 实现具有可扩展服务器的响应式客户端。


笔记

使用方法 1 - 我的 500mb dyno(heroku 服务器)内存不足。

我希望无论采用哪种方法,我都会使用 connection / edge pattern 实现分页

graphql 服务器主要是为我自己的前端服务。

【问题讨论】:

您的问题有点不清楚...这里的假设是,使用第二种方法,您发出一个请求,查询notes,然后每个返回的 id 发出一个请求,这次请求note 字段? 还要求“最佳方法”使这个问题变得广泛并受制于意见。提供一些标准会很有帮助。除了您要解决的服务器上的内存不足之外,还有什么问题。与其问“什么是最好的方法”,不如问哪种方法可以帮助我实现 x、y 和 z? @DanielRearden -- 是的方法 2 需要随后每个返回的 id 一个请求。我尝试编辑问题以在其上添加更多参数 【参考方案1】:

如果您的服务器内存不足,可能是时候升级了。如果您现在内存不足,想象一下当您有多个用户访问您的端点时会发生什么。

解决该特定问题的唯一其他方法是将查询分解为几个较小的查询。但是,您提出的方法存在几个问题:

你最终会用更多的请求来冲击你的服务器和你的数据库 您的 UI 可能需要更长时间才能加载,具体取决于是否需要立即呈现请求的数据 当您的一个请求失败或尝试重试失败的请求时处理场景可能具有挑战性

您已经建议添加分页,我认为将单个大型查询分解为较小的查询会更好。分页不仅有助于提供更好的用户体验,而且通过强制限制页面大小,您可以有效地限制给定查询的大小。

您可以考虑探索的另一个选项是使用deferred queries。考虑到昂贵的查询,此实验性功能是专门添加的。通过延迟 Note 类型上的一个或多个字段,您最初将有效地为它们返回 null,并且它们的值将在它们最终解决后在第二个“补丁”响应中发送。这对于解析成本高昂的字段非常有用,但也可能有助于返回大量数据的字段。

【讨论】:

以上是关于GraphQL:一个大查询与大量小查询的主要内容,如果未能解决你的问题,请参考以下文章

Apollo GraphQL:用于查询返回不同类型对象的模式?

无法使用 graphq-request 表示嵌套对象输入类型的数组

GraphQL,使用 GraphiQL 的查询语法不正确

带有官方 Graphql 教程的“无法在 CreateUser 类型上查询字段 'id'”

我们如何从 GraphQL 的 RequestContextHolder 获取 GraphQL 的 HttpServletRequest(DefaultGlobalContext)(使用 graphq

MySQL切分查询用法分析