Graphql Apollo Client 3.0缓存和命名空间查询

Graphql Apollo Client 3.0缓存和命名空间查询,graphql,apollo,apollo-client,Graphql,Apollo,Apollo Client,关于如何将apollo客户端缓存与组织查询的特定方式结合起来,我有一些问题 因此,我们组织查询的方式是将同一资源上的查询分组到单个命名空间下。例如,我们有两个资源,用户和帐户,我们的查询如下所示 type Query { user: UserQueries account: AccountQueries } type UserQueries { all: [User!]! byId(id: ID!): User } type AccountQueries { all: [

关于如何将apollo客户端缓存与组织查询的特定方式结合起来,我有一些问题

因此,我们组织查询的方式是将同一资源上的查询分组到单个命名空间下。例如,我们有两个资源,
用户
帐户
,我们的查询如下所示

type Query {
  user: UserQueries
  account: AccountQueries
}

type UserQueries {
  all: [User!]!
  byId(id: ID!): User
}

type AccountQueries {
  all: [Account!]!
  byId(id: ID!): Account
}

type User {...}
type Account {...}
由于
查询
类型都不提供ID字段,因此默认情况下,
用户查询
下的第二个查询的响应将替换缓存中第一个查询的数据,即,首先我进行
所有
查询,然后我将返回存储在
用户
字段下的缓存中的一些数据。然后,如果我进行
byId
查询,则
user
下缓存中的数据将被新数据替换

有关此过程的一些问题:

  • 我注意到,即使在
    所有
    数据被
    byId
    数据替换之后,以前获取的用户(规范化的用户)仍然可以在缓存中使用,而我认为它们会被垃圾收集,因为引用丢失了。垃圾收集器不是立即对它们进行垃圾收集,而是以一定的节奏运行吗?还是我完全误解了gc的工作原理
  • 除了为查询类型
    用户
    生成唯一ID之外,还有其他方法保留这两个响应吗
  • 这样命名查询名称空间是个好主意吗

  • 谢谢大家

    正如您所经历的,结果将被另一个查询覆盖,因为缓存不知道从技术上讲,查询总是返回相同的对象

    有两种解决方案:

    您已经确定了第一个:为这些对象提供一个静态ID字段。这太难看了。第二个是为这些查询字段编写
    merge
    函数,如中所述。一般来说,我不认为名称空间是个坏主意,但正如您所看到的,您必须为模式中的任何实体类型编写这个合并函数。因此,我建议节约使用名称空间


    垃圾收集器在阿波罗3中也得到了一些更新。它现在可以定制并随时运行。您可以阅读有关GC的更多信息。不再被引用的对象可能会在缓存中保留一段时间。文档似乎没有指定GC何时运行。通过调用
    client.gc()
    可以手动运行它实际上,Apollo 3使用命名空间查询的正确方法是将
    keyFields
    设置为空数组。 当您这样做时,您会向Apollo显示没有用于合并的id,因此所有内容都应该合并到同一个缓存密钥中。 您不必为此编写合并函数

    它通过
    InMemoryCache
    配置中的
    typePolicies
    选项进行配置

    const Apollo客户端=新Apollo客户端({
    缓存:新的InMemoryCache({
    类型策略:{
    用户查询:{
    关键字字段:[],
    },
    帐户查询:{
    关键字字段:[],
    },
    },
    }),
    });
    
    您知道多少好的名称空间API?谢谢@Herku!我们最终删除了名称空间以使我们的生活更轻松。