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

Jon*_*han 5 node.js apollo graphql apollo-server apollo-client

我知道这个问题由来已久——而且这并不是什么灵丹妙药。但我认为可能有一个固定的模式,我不想发明轮子。

考虑以下两个架构选项:

方法1)我原来的实现

type Query {
  note(id: ID!): Note
  notes(input: NotesQueryInput): [Note!]!
}
Run Code Online (Sandbox Code Playgroud)

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

type DatedId {
  date: DateTime!
  id: ID!
}

type Query {
  note(id: ID!): Note
  notes(input: NotesQueryInput): [DatedId!]!
}
Run Code Online (Sandbox Code Playgroud)

差异是:

使用方法 1) 注释查询将返回可能较大的注释对象的列表

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

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


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

  • 我希望无论采用哪种方法,我都会使用连接/边缘模式实现分页

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

Dan*_*den 3

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

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

  • 您最终将用更多的请求来打击您的服务器和数据库
  • 您的 UI 可能需要更长的时间来加载,具体取决于请求的数据是否需要立即呈现
  • 当您的一个请求失败或尝试重试失败的请求时,处理这种情况可能会很困难

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

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