【问题标题】:Is there a way to add a cache between Apollo Gateway and federated services?有没有办法在 Apollo Gateway 和联合服务之间添加缓存?
【发布时间】:2021-06-21 17:15:39
【问题描述】:

我正在使用 Apollo Federation,但我有一个关于缓存的问题。

现在我有一个这样的查询,我想在哪里找到帖子的作者:

query GetPost {
  post(id: "123") {
    id
    author {
      id
      name
    }
  }
}

Post 是一项服务,而 Author 是另一项服务。 “id”包含在 post 模型中,因为在使用客户端 apollo 库时这是预期的。

当该查询运行时,内部会发出两个请求:每个服务一个。

现在,(由网关)对 post 服务生成的请求非常简单,如下所示:

query {
  post(id: "123") {
    id
  }
}

我每分钟都会收到数千个这样的数据,并希望将它们缓存起来。显然,通过 ID 获取帖子的 ID 永远不会改变,所以每次这样的请求都是浪费。

有没有办法在网关端缓存这个请求?这样它就不会向 post 服务发出请求。

【问题讨论】:

  • 我猜...在Post 类型中没有authorId ...这就是为什么没有简单的可能性来询问帖子作者数据的原因? - 某些<Author/> 组件中的单独请求(缓存在客户端,仅在需要时查询)- 简单地authorById ...另一方面,为什么所有数据都没有在Post 级别上查询并且作者数据没有作为道具传递?为什么它需要单独的查询? ...糟糕的客户端设计?没有优化,没有成本/限制/不需要?

标签: graphql apollo apollo-server apollo-federation


【解决方案1】:

根据Apollo docs,您可以通过扩展 RemoteGraphQLDataSource 类来自定义用于从您的实施服务中检索数据的提取器。自定义提取器可以是任何实现提取规范的函数,在本例中,我使用node-fetch-cache 将查询持久化到网关上的磁盘。

const { ApolloGateway, RemoteGraphQLDataSource } = require("@apollo/gateway");

class CachingDataSource extends RemoteGraphQLDataSource {
    fetcher = require('node-fetch-cache')('./locaCache');
}

const gateway = new ApolloGateway({
    serviceList: [
        { name: "post", url: "http://posts.service" },
        { name: "author", url: "http://author.service" },
    ],
    buildService({ name, url }) {
        if (url === "http://posts.service") {
            return new CachingDataSource({ url, name });
        } else {
            return new RemoteGraphQLDataSource({
                url,
                name
            });
        }
    },
});

【讨论】:

    猜你喜欢
    • 2019-06-22
    • 2020-08-05
    • 2015-07-01
    • 1970-01-01
    • 2019-12-29
    • 2022-09-25
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多