使用 GraphQL 进行 Cloudfront 缓存?

问题描述 投票:0回答:3

在我的公司,我们将 graphql 用于生产应用程序,但仅限于私有资源。

目前我们的公共 API 是带有 Cloudfront 缓存服务的 REST API。我们想将它们转换为 GraphQL API,但问题是:如何使用 GraphQL 正确处理缓存?

我们考虑使用 GET graphql 端点,并在查询字符串上进行缓存,但我们有点担心请求的 URL 的大小(因为我们支持 IE9+ 并出售给有时带有真正虚拟代理和防火墙的学校)

所以我们想使用 POST graphQL 端点,但是...cloudfront 无法根据其主体缓存请求

有人有想法/最佳实践可以分享吗? 谢谢

node.js amazon-web-services amazon-cloudfront graphql
3个回答
2
投票

今天最好的两个选择是:

  • 使用专门的缓存解决方案,例如FastQL.io
  • 通过 GET 使用持久查询,其中一些查询保存在您的服务器上并通过 GET 按名称访问

*全面披露:在遇到这些问题但没有好的解决方案后,我开始使用 FastQL。


2
投票

我在纸上探索过但尚未实现的一个选项是在请求触发模式下使用 Lambda@Edge 将客户端 POST 转换为 GET,这可能会导致缓存命中。

这样,客户端仍然可以使用 POST 发送 GQL 请求,并且在尝试计算转换后的 GET 请求的最大 URL 长度时,您正在使用 AWS 中的少量受控服务(这些限制通常相当高) .

仍然会有长度限制,但是一旦您有 16kB+ GQL 请求,可能是时候采取在服务器上使用预定义查询的其他建议并仅按名称引用它们了。

它确实有一个缺点,即请求触发器 Lambda 在每个请求上运行,甚至是缓存命中,因此会产生一些成本,尽管 lambda 本身应该非常快速/简单。


1
投票

我不确定它是否有特定的名称,但我在野外看到了一种模式,其中 graphQL 查询本身托管在具有特定 id 的后端上。 它的灵活性要差得多,因为它需要内置预定义的查询。

客户端只需发送要使用的预定义查询的参数/参数和 ID,这将是您的缓存密钥。类似于 HTTP 缓存如何处理对

/my-profile
的经过身份验证的请求,CloudFront 根据标头中的身份验证令牌提供不同的响应。

客户端如何发送取决于你的 graphQL 后端实现。 您可以将其作为白名单标头或查询字符串传递。

因此,如果后端定义了一个如下所示的查询

(使用伪代码)

const MyQuery = gql`
query HeroNameAndFriends($episode: int) {
  hero(episode: $episode) {
    name
    friends {
      name
    }
  }
}
`

那么您的要求将是类似

api.app.com/graphQL/MyQuery?episode=3

话虽这么说,您是否确实测量过您的查询不适合 GET 请求?如果您需要 CDN 缓存,我会说使用 GET 请求,并对不符合限制的请求使用上述方法。

编辑:似乎它有一个名称:自动持久查询。 https://www.apollographql.com/docs/apollo-server/performance/apq/

保留 POST 请求的另一种选择是在 CloudFront 上使用 Lambda@Edge 并使用 DynamoDB 表来存储缓存,类似于 CloudFlare 工作人员的做法。

async function handleRequest(event) {
    let cache = caches.default
    let response = await cache.match(event.request)
    
    if (!response){
      response = await fetch(event.request)
      if (response.ok) {
        event.waitUntil(cache.put(event.request, response.clone()))
      }
    }
          
    return response
}

一些相关阅读材料

© www.soinside.com 2019 - 2024. All rights reserved.