如何配置 apollo 缓存以根据父元素的主键唯一标识子元素

How to configure apollo cache to uniquely identify a child elements based on their parent primary key

为没有自己的 ID 但在其父结构中唯一的子数组字段配置 apollo 缓存规范化的正确方法是什么?

假设我们有以下架构:

type Query {
  clients: [Client!]!
}

type Client {
  clientId: ID
  name: String!
  events: [Events!]!
}

type Events {
  month: String!
  year: Int!
  day: Int!
  clients: [Client!]!
}

起初我以为我可以使用多个keyFields来实现像这样的唯一标识符:

const createCache = () => new InMemoryCache({
  typePolicies: {
    Event: {
      keyFields: ['year', 'month', 'name'],
    },
  },
});

每天不会超过 1 个事件,因此可以肯定地说事件对于基于日期的客户来说是唯一的

但创建的缓存条目缺少 clientId(在缓存键中),因此无法区分同一日期但针对不同客户端的 2 个事件

是否有适当的方法来为这种关系配置 typePolicies

例如,关键字段可以设置为使用 subfield:

const cache = new InMemoryCache({
  typePolicies: {
    Book: {
      keyFields: ["title", "author", ["name"]],
    },
  },
});

The Book type above uses a subfield as part of its primary key. The ["name"] item indicates that the name field of the previous field in the array (author) is part of the primary key. The Book's author field must be an object that includes a name field for this to be valid.

在我的例子中,我想使用父字段作为主键的一部分

如果您无法添加唯一的事件 ID,则退而求其次 disable normalization:

Objects that are not normalized are instead embedded within their parent object in the cache. You can't access these objects directly, but you can access them via their parent.

为此,您将 keyFields 设置为 false:

const createCache = () => new InMemoryCache({
  typePolicies: {
    Event: {
      keyFields: false
    },
  },
});

基本上每个 Event 对象都将存储在其父 Client 对象下的缓存中。