有没有办法在 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 工具一起使用?