繁体   English   中英

GraphQL/Apollo 客户端:如果查询是先前查询的子集,则从缓存中获取数据

[英]GraphQL/Apollo Client: get data from cache if a query is a subset of a previous query

我是 GraphQL 的新手,我认为它会自动执行此操作。

例如,如果我获取帖子列表,然后打开单个帖子,则该帖子的数据已经在 memory 中。 我希望 GraphQL 能够重新使用缓存中的数据,但它会发出另一个网络请求。

架构类似于:

  type Query {
    posts: [Post]
    post(id: ID): Post
  }

我正在使用反应。 PostsRoute中,我有:

  useQuery(gql`
    query {
      posts {
        id
        title
      }
    }
  `);

PostRoute ,我有:

  useQuery(gql`
    query {
      post(id: ${postId}) {
        id
        title
      }
    }
  `);

我需要为 Apollo 配置什么来自动使用缓存的数据吗? 或者这是 Apollo 默认不支持的东西?

阿波罗 2 号

如果您使用的是 Apollo 2,那么您正在寻找的可能是cacheRedirects 它用于拦截查询并使用缓存解决它。 链接的文档实际上准确地解释了您的用例,因此我建议您查看它,但为了后代,这是我个人的做法(适应您的情况)。

在实例化它时,在InMemoryCache选项中,添加一个cacheRedirects字段并为您的post查询指定一个自定义解析器,如下所示:

const cache = new InMemoryCache({
  cacheRedirects: {
    Query: {
      post: (_, {id}, {getCacheKey}) => getCacheKey({__typename: "Post", id}),
    },
  },
});

这假设您的帖子的__typenamePost 自定义解析器的第一个参数是ROOT_QUERY的结果,我们在这里不使用它。 第二个参数是传递给查询的 arguments (此处为{id: "some_id"} ),第三个参数是上下文,包含clientcachegetCacheKey 这里只有getCacheKey对我们有用。 该方法采用__typenameid ,并在缓存中返回其键。

这样就完成了自定义解析器。 现在,当您查询post(id: some_id)时,它将查看自定义解析器,接收缓存键并从缓存中返回与该键匹配的结果。

阿波罗 3 号

cacheRedirects在 Apollo 3 中已被移除,但同样的功能可以通过field policies来实现。 实例化InMemoryCache时仍然需要进行设置,但略有不同:

const cache = new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
        post: (_, {args, toReference}) => toReference({__typename: "Post", id: args.id}),
      },
    },
  },
});

我们在Query类型的字段post上定义了一个字段策略。 请注意,第二个参数现在包括args和辅助实用程序。 这包括toReference ,这基本上是新的getCacheKey

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM