Apollo 服务器端缓存:缓存的关键是什么?

Ale*_*els 4 caching apollo graphql

我正在阅读Apollo 服务器端缓存的文档,但没有看到任何有关缓存通常如何设置键控的内容。

我需要的是一个以响应中包含的对象 ID 为关键的缓存,而不是以从查询中获取的内容为关键。

例如,假设下面的 Person 对象由 ID 字段唯一标识,并且 hasShortHair 字段的计算成本很高,但很少发生变化。

type Person {
  id: String!
  hasShortHair: Boolean!
}
Run Code Online (Sandbox Code Playgroud)

假设有 2 种不同的查询类型可以返回 Person:

getPerson(id: String!): Person!
getAllPeople: [Person!]!
Run Code Online (Sandbox Code Playgroud)

理想情况下,对于具有给定 ID 的人,如果最近通过 getPerson 或 getAllPeople 获取该人,那么我想缓存为该人计算的 hasShortHair 值,并将该缓存用于getPerson和 getAllPeople返回该人的查询。

像下面这样的设置可以达到这个目的吗?(基于文档中的书籍示例

type Person @key(fields: "id") @cacheControl(maxAge: 30) {
  id: String!
  hasShortHair: Boolean!
}
Run Code Online (Sandbox Code Playgroud)

或者对此的缓存仍然是按请求键控的吗?

JC *_*and 5

ApolloServerPluginCacheControl插件解析特定字段和类型的缓存注释(例如通过@cacheControl指令),并据此确定特定请求的总体缓存策略。

然后,根据计算出的请求缓存策略,Cache-Control在响应对象上设置标头。

您可以在 Github 上自行查看代码

这就是它的全部作用,不涉及缓存键。

然后,客户端或 Apollo 前面的某些缓存代理有责任使用Cache-Control标头进行实际缓存。

标头的格式如下:

Cache-Control: max-age=60, private
Run Code Online (Sandbox Code Playgroud)

max-age根据解释所有提示的规则确定cacheControl

如果你想用 Apollo 缓存响应,你可以使用response-cache-plugin

更多信息在这里: https://www.apollographql.com/docs/apollo-server/performance/caching/#caching-with-responsecacheplugin-advanced

使用响应缓存插件,您可以将整个响应缓存在 Redis 或 memcached 中。

在这种情况下,缓存键基于请求本身,即来自插件文档:cached responses are only used for identical requests

所以,回答你的问题:

理想情况下,对于具有给定 ID 的人,如果最近通过 getPerson 或 getAllPeople 获取该人,那么我想缓存为该人计算的 hasShortHair 值,并将该缓存用于 getPerson 和getAllPeople 查询返回该人。

缓存是针对每个请求/响应的,而不是针对每个单独解析的字段。

来自ApolloServerPluginResponseCache 代码

All writes will be under keys that start with 'fqc:' and are followed by a fixed-size cryptographic hash of a JSON object with keys representing the query document, operation name, variables, and other keys derived from the sessionId and extraCacheKeyData hooks.

因此,如果您想缓存各个字段,则必须添加自己的缓存机制来做到这一点。