从 apollo 缓存读取查询,查询尚不存在,但所有信息都已存储在缓存中

Posted

技术标签:

【中文标题】从 apollo 缓存读取查询,查询尚不存在,但所有信息都已存储在缓存中【英文标题】:Read query from apollo cache with a query that doesn't exist yet, but has all info stored in the cache already 【发布时间】:2019-03-15 14:34:41 【问题描述】:

我有一个可以输入此查询的 graphql 端点:

fragment ChildParts 
  id
  __typename


fragment ParentParts 
  __typename
  id
    children 
   edges
       node 
         ...ChildParts 
       
   


query 
  parents 
    edges
      nodes 
        ...ParentParts
      
    
  

执行时,它返回如下内容:

"data": 
  "edges": [
     "node": 
       "id": "<some id for parent>",
       "__typename": "ParentNode",
       "children": 
         "edges": [
           node: 
             "id": "<some id for child>",
             "__typename": "ChildNode"
           ,
           ...
         ]
       
     ,
     ...   
  ]

现在,使用 apollo 客户端,在突变后,我可以从缓存中读取此查询,并更新/添加/删除任何 ParentNode 以及任何 ChildNode,但我必须检查此查询返回的结构。

现在,我正在寻找一种从缓存中获取 ChildNode 列表的可能性(其中已经有这些,因为缓存是作为平面列表创建的),以使嵌套数据的更新更容易一些。是否有可能从缓存中读取查询,而之前没有从服务器读取相同的查询?

【问题讨论】:

Apollo Client 有所谓的cache redirects 供您使用。另请参阅我对这个问题的回答:***.com/a/50839798/3849167 你可以为列表添加缓存重定向吗?或者您可以将空值写入缓存以获取 ID?因为我的用例涉及删除一个节点,并且我想防止遍历整个父树来查找要删除的子节点。 【参考方案1】:

您可以使用客户端的readFragment 方法从缓存中检索任何单个项目。这只需要 id 和一个片段字符串。

const todo = client.readFragment(
  id,
  fragment: gql`
    fragment fooFragment on Foo 
      id
      bar
      qax
    
  `,
)

注意id这里是dataIdFromObject函数返回的缓存键——如果你没有指定自定义函数,那么(假设__typename和id或_id字段存在)默认实现就是:

$result.__typename:$result.id || result._id

如果您提供了自己的 dataIdFromObject 函数,则需要提供该函数返回的任何 id。

正如@Herku 所指出的,根据用例,还可以使用缓存重定向在解析另一个查询时利用为一个查询缓存的数据。这是设置 InMemoryCache 的一部分:

const cache = new InMemoryCache(
  cacheRedirects: 
    Query: 
      book: (_, args,  getCacheKey ) =>
        getCacheKey( __typename: 'Book', id: args.id )
    ,
  ,
)

不幸的是,在撰写此答案时,我不相信有任何方法可以通过 id 删除缓存的项目。围绕这一点正在讨论here(原始问题here)。

【讨论】:

以上是关于从 apollo 缓存读取查询,查询尚不存在,但所有信息都已存储在缓存中的主要内容,如果未能解决你的问题,请参考以下文章

从缓存中读取查询导致在对象未定义上找不到字段 <field>

GraphQL 角度阿波罗客户端。从缓存中读取抛出错误,但对服务器的相同查询工作正常

如何通过 ID 从 Apollo 缓存中读取嵌套对象?

Apollo 从缓存中查询对象值

Apollo 查询从缓存中获取了错误的数据

如何从 Apollo 缓存中查询没有 ROOT_QUERY 上的查询