了解AWS AppSync JavaScript SDK中的Apollo客户端缓存和开放式UI

时间:2018-09-07 11:32:02

标签: javascript graphql apollo

我正在尝试使用AWS AppSync JavaScript SDK在Apollo客户端中实现缓存,但是我在努力理解首先要使用缓存的最佳方式,其次我需要进行任何更改以适应Apollo V2教程的工作使用AppSync SDK。

关于使用缓存,我有一个对象列表,然后我想从该列表中查看和修改单个对象。关于如何更新列表中的某些内容的教程很多,但是我宁愿运行第二个查询,该查询通过其ID获取单个对象,以便页面始终可以工作而不必先浏览列表。

缓存是否足够聪明,以至于知道通过查询Y和Z获得的对象X是同一个对象,并且将同时进行更新?如果没有,是否有任何文档说明如何编写将同时更新列表中的对象和本身的更新?

如果没有文档,那么我将尝试自行解决并发布代码(因为它很可能无法正常工作)。

关于第二个问题,我已经使应用程序正常运行,并使用Amplify进行了API查询以进行身份​​验证,但是我不确定如何正确实现缓存。创建客户端时是否需要指定缓存,或者SDK具有内置缓存?如何访问缓存?是否只是像这些教程中那样通过查询客户端? https://www.apollographql.com/docs/react/advanced/caching.html

1 个答案:

答案 0 :(得分:5)

我将首先回答您的第二个问题:

  

关于第二个问题,我已经使应用程序正常运行,并使用Amplify进行了API查询以进行身份​​验证,但是我不确定如何正确实现缓存。创建客户端时是否需要指定缓存,或者SDK具有内置缓存?如何访问缓存?是否只是像这些教程中那样通过查询客户端?

好的。所以这里有点毛茸茸的-似乎是在GraphQL的主要客户端库(Apollo,Relay等)进行全面检查的时候部署了AppSync,因此AWS实际上围绕Apollo Client创建了一个包装器(可能出于稳定的API目的),然后公开自己的处事方式。只需快速浏览一下代码,就好像它们具有自己的专有且未记录的处理方式that involves websockets, their authentication protocols, a redux store, offline functionality, ssr, etc)。因此,如果没有明确说明herehere,则说明您处于未知领域。

幸运的是,他们提供的(现在还有更多)所有东西已经现在记录的方式在底层的Apollo Client中实现。更为幸运的是,AppSync客户端似乎将大多数与GraphQL实际相关的内容直接转发到内部Apollo缓存,并允许您在cacheOptions下传递配置选项,因此您可以使用Apollo进行大多数配置您可以使用AppSync客户端(下面有更多内容)做客户端。

不幸的是,您无法直接使用AppSync客户端访问缓存(它们已隐藏它以确保其公共API在波动的生态系统中保持稳定)。但是,如果您确实需要更多控制权,则可以轻松地在自己的Apollo客户端实例中复制在AppSync客户端中实现的大多数内容,从而可以完全控制(您可以使用open-source AppSync code基础)。由于GraphQL前端和后端是解耦的,因此没有理由不能使用自己的Apollo Client与AppSync服务器连接(对于大型,严肃的项目,这就是我要做的,因为Apollo Client有很多文档记录并正在积极开发中。

  

缓存是否足够聪明,以至于知道通过查询Y和Z获得的对象X是同一个对象,并且将同时进行更新?如果没有,是否有任何文档说明如何编写将同时更新列表中的对象和本身的更新?

第一部分与Apollo客户端和AppSync客户端有关。

是的!那是Apollo客户端的一大优点-每次查询时,它都会尝试更新缓存。缓存是归一化的键值存储,其中所有对象都存储在顶层,该键是对象的__typenameid属性的组合。 Apollo客户端会自动将__typename添加到所有查询中(尽管您必须手动将id添加到您的查询中-否则,它会退回到查询路径本身作为键[非常健壮])。

docs很好地概述了该机制。

现在,您可能需要做一些更高级的工作。例如,如果您的GraphQL模式使用了id以外的一些唯一对象标识符,则您必须为映射到它的dataIdFromObject提供一些功能。

此外,有时在进行查询时,在发出网络请求之前,缓存很难准确地知道您要查询的内容。为了缓解此问题,他们提供了cache redirect机制。

最后,也许是最复杂的,是如何更新分页查询(例如,有序列表中的任何内容)中的东西顺序。为此,您必须使用@connection指令。由于这是基于relay connection spec的,因此建议您略读一下。

奖金:要查看运行中的缓存,我建议使用Apollo client dev tools。这是个小问题,但至少可以使您了解本地缓存实际发生的情况-如果使用AppSync,则无法使用。


因此,除了上述所有有关设置和配置缓存的信息之外,您还可以在应用程序运行期间控制数据和对缓存的访问(如果直接使用Apollo Client而不是AppSyncClient)。

Direct Cache Access docs指定可用的方法。但是,由于大多数更新仅根据您进行的查询自动发生,因此您不必经常使用这些更新。但是,它们的一种用途是进行复杂的UI更新。例如,如果您进行了一个变异,从列表中删除了一个项目,而不是重新查询整个列表(更新缓存,但是会花费更多网络数据,解析和规范化的代价) ),您可以使用readQuery / writeQueryupdate突变选项定义自定义缓存更新。这与optimisticResponse配合使用也很不错,如果您正在寻找乐观的用户界面,则应该使用它。

此外,您可以使用fetchPolicy or errorPolicy options之一来选择是使用还是绕过缓存(或更高级的策略)。