繁体   English   中英

使用Apollo重写部分GraphQL查询的最佳实践?

[英]Best practices for refetching part of a GraphQL query with Apollo?

我有以下react-apollo -wrapped GraphQL查询:

user(id: 1) {
  name
  friends {
    id
    name
  }
}

从语义上表示,它获取ID为1的用户,返回其name ,并返回其所有朋友的idname

然后我在一个组件结构中渲染它,如下所示:

graphql(ParentComponent)
  -> UserInfo
  -> ListOfFriends (with the list of friends passed in)

这一切都对我有用。 但是,我希望能够为当前用户重新获取朋友列表。

我可以在父组件上执行this.props.data.refetch()并传播更新; 但是,我不确定这是最好的做法,因为我的GraphQL查询看起来更像这样,

user(id: 1) {
  name
  foo1
  foo2
  foo3
  foo4
  foo5
  ...
  friends {
    id
    name
  }
}

虽然我唯一想要回复的是朋友名单。

干净地构建这个的最佳方法是什么? 我正在考虑将最初跳过的GraphQL提取器绑定到ListOfFriends组件,这可以在必要时触发,但是想要了解如何最好地完成此操作。

提前致谢。

我不知道为什么你的问题被贬低,因为我认为这是一个非常有效的问题。 GraphQL的一个卖点是“一次性获取更少”。 客户可以从后端非常简单地决定它需要什么。 使用以前需要多个端点的深层嵌套图形查询现在可以在单个查询中表示。 同时可以避免过度取样。 现在你发现自己有一个大查询,一切都加载,并且没有n + 1个查询瀑布。 但是现在您知道大查询中的一些字段可能会随时更改,并且您希望使用服务器中的新数据主动更新缓存。 Apollo提供了refetch字段,但是它加载了整个查询,这显然是过度获取 ,而不是在GraphQL中出售给我的。 让我提供一些解决方案:

过早优化?

真正的问题是程序员花费了太多时间来担心在错误的地方和错误的时间提高效率; 过早优化是编程中所有邪恶(或至少大部分)的根源。 - 唐纳德克努特

有时我们会尝试优化太多而不先测量。 先写一下简单的方法,然后看看它是否真的是一个问题。 究竟什么慢? 网络? 查询中的特定字段? 查询的大小?

在你分析了究竟什么是慢的之后我们可以开始研究改进:

Refetch和include / skip指令

使用指令可以根据变量从查询中排除字段。 重新获取功能可以指定与初始查询不同的变量 这样,您可以在重新获取查询时排除字段。

拆分查询

单页应用程序是一个好主意。 HTML是在客户端生成的,页面不必花费昂贵的时间去服务器来呈现新页面。 但很快SPA就变得很大,代码分裂成为一个问题。 现在我们基本上回到服务器端渲染并将应用程序拆分成页面。 这同样适用于GraphQL。 有时查询太大,应该拆分。 您可以拆分UserInfoListOfFriends的查询。 在缓存中,字段将被合并。 使用查询批处理,两个查询将在同一请求中发送,并且正确实现每个请求资源缓存的GraphQL服务器(例如使用Dataloader )几乎不会注意到差异。

订阅

也许你已经准备好使用订阅了。 订阅从服务器发送已更改字段的更新。 这样您就可以订阅用户的朋友并实时获取更新。 好消息是Apollo Client,Relay和许多服务器实现已经为订阅提供支持。 坏消息是它需要通常对技术堆栈提出不同要求的websockets而不是纯HTTP。

withApollo() - > this.client.query

这应该只是你的最后手段! 使用react-apollowithApollo高阶组件,您可以直接注入ApolloClient实例。 您现在可以使用this.client.query()执行查询。 { user(id: 1) { friendlist { ... } } }可用于获取好友列表并更新缓存,这将导致更新您的组件。 这可能看起来像你想要的,但可以在应用程序的后期阶段困扰你。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM