将数据源添加到 Keystone 5 中的 apollo 配置选项时出现缓存问题

Cache problem when adding data sources to the apollo config option in Keystone 5

第二次向服务器执行请求时,returns的结果始终是缓存的结果,即使第一次请求改变了实体。

这里是 dataSources.js 文件,它导入每个 class 数据源的两个实例:

  1. legacyUserApi = new LegacyUserApi();
  2. legacyMailApi = new LegacyMailApi();
import legacyUserApi from './LegacyUserApi';
import legacyMailApi from './LegacyMailApi';

export default () => ({
  legacyUserApi,
  legacyMailApi
});

并在 keystone.js 文件中导入它:

import dataSources from './dataSources';

const apps = [
  new GraphQLApp({
    apiPath: API_PATH,
    apollo: {
      dataSources,
      introspection: isDev
    }
  })
]

Keystone js 使用 Apollo Server 所以我查看了他们的 documentation:

Apollo Server calls this function for every incoming operation. Also as shown, the function should create a new instance of each data source for each operation.

所以 dataSources.js 文件应该导入 class 而不是 instance 这样 Apollo Server 就会创建每个请求都有一个新实例。

import LegacyUserApi from './LegacyUserApi';
import LegacyMailApi from './LegacyMailApi';

export default () => ({
  legacyUserApi: new LegacyUserApi(),
  legacyMailApi: new LegacyMailApi()
});

HTTP 响应中有 many ways caching can be used on top of Apollo Server but your question doesn't indicate which you're using. Ultimately, most of them set a Cache-Control header,所以我们假设这里就是这种情况。

此 header 由浏览器和位于它与服务器之间的任何共享缓存(例如 CDN 或代理)解释。一旦缓存,服务器通常没有任何机制来使存储的副本无效。这可以通过为最初将被缓存的响应设置正确的 header 指令来缓解。例如,包括 must-revalidate 指令或设置短 max-age.

或者,设置 private 指令将只允许在浏览器中缓存请求。随后的 HTTP 请求可以指定 max-age=0, no-cache 以强制再次获取数据(例如,在进行更改之后)。这可能允许您为单个用户解决问题,但显然,您失去了共享缓存的好处。

如果不进一步了解您的缓存配置、基础结构和发出的请求,就很难给出具体的建议。也许您可以使用 curl 复制更新您的问题?这样您就可以将服务器行为与浏览器行为隔离开来。