监控缓存数据
根据缓存更改更新UI
因为你的规范化缓存可以去除你的GraphQL数据的重复(使用适当的缓存ID)
在执行一个操作时,你可以使用ApolloCall.watch
方法,以便在关联的缓存数据发生变化时自动通知:
apolloClient.query(TodoDetailsQuery()).watch().collect { response ->// This code now executes on response *and*// every time cached data changes}
让我们看一下一些例子。
监控查询
假设我们正在开发一个协同待办事项列表应用程序,该应用程序执行这两个查询
# AllTodos.graphql# Gets all todo itemsquery AllTodos {items {idcompletedtitle}}
# TodoDetails.graphql# Gets one todo item's detailsquery TodoDetails($id: String!) {item(id: $id) {idcompletedtitlecontent}}
应用程序的主要视图执行 AllTodos
查询 以显示待办事项列表,包括每个项目的 Item
标题和 completed
完成 状态。以下是一个示例响应:
{"data": {"items": [{"id": "0","title": "Write code for Apollo Kotlin","completed": true,},{"id": "1","title": "Write documentation for Apollo Kotlin","completed": false,}]}}
当用户在UI中选择一个特定项时,应用程序会执行 TodoDetails
以显示该项目的全部详情。由于这是一个 协作 待办事项清单,这些详情可能在执行 AllTodos
(即另一用户进行更改) 之后在服务器端发生变化。
在这种情况下,TodoDetails
查询可能返回如下内容:
{"data": {"item": {"id": "1","title": "Write documentation for Apollo Kotlin","completed": true,"content": "Don't forget docs about the normalized cache!"}}}
使用已规范化的缓存和配置适当的缓存ID,此更新的 Item
将自动与从 AllTodos
返回的现有 缓存 的 Item
合并。然而,我们的UI不会自动更新以反映新的缓存数据。
为了处理这种情况,我们可以在执行任何查询时调用 watch()
:
apolloClient.query(TodoDetailsQuery()).watch().collect { response ->// This code now executes on response *and*// every time cached data changes}
现在,如果另一个操作更新了该查询的缓存 字段,我们的UI将以它第一次获取查询时使用的相同逻辑进行渲染。
在变异之后更新缓存
有时您需要更新缓存数据来反映由 变异 产生的更改。
例如,在我们的待办事项应用程序中,用户可能会勾选完成某个项目。这可能会执行以下变异以修改 Item
's completed
's 字段:
mutation SetTodoCompleted($id: String!, $completed: Boolean!) {setTodoCompleted(id: $id, completed: $completed) { # Returns the modified Itemid}}
正如所写,这个变异会在服务器上更新 completed 字段,但在 缓存中不会更新。这是因为变异响应不包括 Item 的 completed 字段。
要自动使用新值更新缓存,您需要请求响应中所有修改的字段:
mutation SetTodoCompleted($id: String!, $completed: Boolean!) {setTodoCompleted(id: $id, completed: $completed) {id# Ask for `completed` to update the cachecompleted}}
由于上面的 setTodoCompleted
字段返回了包含 Apollo Kotlin 端的 id
和 completed 字段的 Item
类型,Apollo Kotlin 可以使用新数据更新缓存的 Item
条目。此外,任何监听此 Item
's completed
字段的监视器将被自动通知。
乐观更新
通常可以在 GraphQL 服务器 返回结果之前预测一个 突变 的最可能结果。这之后,Apollo Kotlin 可以使用这个 "最可能的结果" 来乐观更新您的 UI,使您的应用对用户更迅速响应用户的行为。
您可以通过 optimisticUpdates 方法提供乐观数据,如下所示:
apolloClient.mutation(SetTodocompletedMutation(id = "1", completed = true)).optimisticUpdates(SetTodocompletedMutation.Data(id = "1",completed = true,)).execute()
此乐观数据将立即写入缓存,并通知任何相应数据的观察者。然后,当 操作 返回时,缓存会根据任何更改再次更新,观察者也会再次被通知。如果乐观数据是正确的,第二次缓存更新对用户来说是不可见的,因为没有数据更改。