我有以下 react-apollo
-wrapped GraphQL 查询:
user(id: 1) {
name
friends {
id
name
}
}
按照语义表示,它获取 ID 为 1 的用户,返回其 name
,并返回其所有用户的 id
和 name
friend 。
然后我将其呈现在如下组件结构中:
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
}
}
虽然我唯一想重新获取的是 friend 列表。
干净地构建它的最佳方法是什么?我正在考虑将最初跳过的 GraphQL 获取程序绑定(bind)到 ListOfFriends
组件,该组件可以根据需要触发,但希望获得有关如何最好地完成此操作的一些指导。
提前致谢。
最佳答案
我不知道为什么你的问题被否决了,因为我认为这是一个非常有效的问题。 GraphQL 的卖点之一是“同时获取更少和更多”。客户可以从后端非常精细地决定它需要什么。使用以前需要多个端点的深度嵌套的图形查询现在可以在单个查询中表达。同时可以避免过度获取。现在您发现自己有一个大查询,所有内容都立即加载并且没有 n+1 查询瀑布。但是现在您知道您的大查询中的一些字段不时会发生变化,并且您希望使用来自服务器的新数据主动更新缓存。 Apollo 提供了 refetch
字段,但它加载了整个查询,这显然是 overfetching 卖给我的,因为在 GraphQL 中不再是一个问题。让我提供一些解决方案:
过早优化?
The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming. - Donald Knuth
有时我们会在没有先测量的情况下尝试优化太多。先用简单的方法写,然后看看它是否真的是个问题。到底什么是慢?网络?查询中的特定字段?查询的绝对大小?
在您分析出究竟是什么地方慢了之后,我们可以开始着手改进:
重新获取和包含/跳过指令
使用 directives您可以根据变量从查询中排除字段。 refetch function can specify different variables比最初的查询。这样您就可以在重新获取查询时排除字段。
拆分查询
单页应用是个好主意。 HTML 是在客户端生成的,页面不必昂贵地访问服务器来呈现新页面。但很快 SPA 变得很大,代码拆分成为一个问题。现在我们基本上回到服务器端渲染并将应用程序拆分为页面。这同样适用于 GraphQL。有时查询太大,应该拆分。您可以拆分对 UserInfo
和 ListOfFriends
的查询。在缓存内部,字段将被合并。用query batching这两个查询将在同一个请求中发送,并且正确实现每个请求资源缓存的 GraphQL 服务器(例如使用 Dataloader )几乎不会注意到差异。
订阅
也许您已经准备好使用订阅了。订阅从服务器发送已更改字段的更新。这样您就可以订阅用户的 friend 并实时获得更新。好消息是 Apollo Client、Relay 和许多服务器实现已经提供了对订阅的支持。坏消息是它需要 websockets,这些 websockets 通常对您的技术堆栈提出与纯 HTTP 不同的要求。
withApollo()
-> this.client.query
这应该是您最后的选择!使用react-apollo的 withApollo
高阶组件你可以直接注入(inject) ApolloClient
实例。您现在可以使用 this.client.query()
执行查询。 { user(id: 1) { friendlist { ... } } }
可用于仅获取好友列表并更新缓存,这将导致组件更新。这可能看起来像您想要的,但可能会在应用程序的后期阶段困扰您。
关于javascript - 使用 Apollo 重新获取部分 GraphQL 查询的最佳实践?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48067366/