有没有办法在 Apollo Gateway 和联合服务之间添加缓存?

Posted

技术标签:

【中文标题】有没有办法在 Apollo Gateway 和联合服务之间添加缓存?【英文标题】:Is there a way to add a cache between Apollo Gateway and federated services? 【发布时间】: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 级别上查询并且作者数据没有作为道具传递?为什么它需要单独的查询? ...糟糕的客户端设计?没有优化,没有成本/限制/不需要? 【参考方案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
            );
        
    ,
);

【讨论】:

以上是关于有没有办法在 Apollo Gateway 和联合服务之间添加缓存?的主要内容,如果未能解决你的问题,请参考以下文章

Apollo 网关在 docker-compose 中不起作用

GraphQL Apollo Federation-JVM 中 @extends 类型的解析器问题

为联合服务 apollo GraphQL 中的架构更改自动重新加载网关

如何将 Apollo-Gateway 与 swagger-to-graphql 工具一起使用?

有没有办法在 Chrome DevTools 中调试 Apollo GraphQL 订阅?

父服务关闭时,Apollo 联合网关无法加载