Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/471.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用Apollo重新蚀刻部分GraphQL查询的最佳实践?_Javascript_Reactjs_Graphql_Apollo_React Apollo - Fatal编程技术网

Javascript 使用Apollo重新蚀刻部分GraphQL查询的最佳实践?

Javascript 使用Apollo重新蚀刻部分GraphQL查询的最佳实践?,javascript,reactjs,graphql,apollo,react-apollo,Javascript,Reactjs,Graphql,Apollo,React Apollo,我有以下react apollo包装的GraphQL查询: user(id: 1) { name friends { id name } } 如语义所示,它获取ID为1的用户,返回其名称,并返回其所有好友的ID和名称 然后,我将其呈现在组件结构中,如下所示: graphql(ParentComponent) -> UserInfo -> ListOfFriends (with the list of friends passed in) 这一切

我有以下
react apollo
包装的GraphQL查询:

user(id: 1) {
  name
  friends {
    id
    name
  }
}
如语义所示,它获取ID为1的用户,返回其
名称
,并返回其所有好友的
ID
名称

然后,我将其呈现在组件结构中,如下所示:

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中,我不再担心这个问题。让我提供一些解决方案:

过早优化? 真正的问题是程序员花了太多的时间在错误的地点和错误的时间担心效率;过早优化是编程中所有罪恶(或至少大部分)的根源-Donald Knuth

有时,我们试图优化太多而不首先进行测量。先用简单的方法写,然后看看这是否真的是个问题。到底什么东西慢?网络?查询中的特定字段?查询的规模究竟有多大

在您分析了什么是慢的之后,我们可以开始考虑改进:

重新蚀刻和包含/跳过指令 使用可以根据变量从查询中排除字段。该查询比初始查询更有效。这样,您可以在重新提取查询时排除字段

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

订阅 也许你已经准备好使用订阅了。订阅从服务器发送已更改字段的更新。通过这种方式,您可以订阅用户的好友并实时获取更新。好消息是Apollo客户端、中继和许多服务器实现已经提供了对订阅的支持。坏消息是,它需要WebSocket,这些WebSocket通常会对您的技术堆栈提出与纯HTTP不同的要求

withApollo()
->
this.client.query

这应该是你最后的选择!使用的
with Apollo
高阶组件,您可以直接注入
Apollo客户端
实例。现在可以使用
this.client.query()
执行查询
{user(id:1){friendlist{…}}}
可用于获取好友列表并更新缓存,从而更新组件。这可能看起来像你们想要的,但在应用程序的后期阶段可能会困扰你们。

我相信阿波罗确实提供了外部缓存box@mehulmpt是的,我明白;但是,我不希望缓存;我想重新描述一个问题的一部分,我认为“什么是干净地构建这个问题的最佳方式”这个问题太主观了。你能不能换个说法,这样就不那么主观了?太棒了。非常感谢您的深刻见解。