将 GraphQL 请求路由到不同区域的 API,服务不同的内容但使用相同的模式

Route GraphQL requests to APIs in different regions serving different content but using same schema

我们在多个 AWS 区域使用 GraphQL API 部署后端服务。每个地区的 GraphQL 模式都是相同的,但服务提供地区特定的数据。 Apollo federation 似乎没有解决这个话题,因为我们不想合并不同的模式。我们的问题也不在于选择最近的区域。客户端选择特定区域以访问该区域提供的数据。

使用 REST,反向代理可以根据路径参数将请求转发到目标区域。然而,在 GraphQL 中,所有请求都针对同一个端点。

将 GraphQL 请求路由到使用相同架构但提供不同内容的不同区域的最佳做法是什么?

编辑:也许同样重要的是要注意我们也在使用 GraphQL 订阅。最好避免连接到客户端中的多个端点 - 如果可能的话。

无论REST还是GraphQL,我认为全局路由必须在请求到达其中一个区域服务之前完成。

因此,例如,使用 Route 53,您可以创建不同的子域 us.example.comeurope.example.com,其中每个都指向相应的区域 GraphQL API。

如果您想在同一区域内跨AZ路由,那么您可以使用ELB。

我们选择了 Apollo Links。每个后端都部署在不同的区域,提供自己的 GraphQL API 端点。

前端保留所有可用区域端点的列表并设置 directional links。我们可以通过设置上下文变量 select 相应的 link。

import { ApolloLink, HttpLink } from '@apollo/client';
import { RetryLink } from '@apollo/client/link/retry';

const directionalLink = new RetryLink().split(
  (operation) => operation.getContext().region === "us",
  new HttpLink({ uri: "http://us-endpoint/v1/graphql" }),
  new RetryLink().split(
    (operation) => operation.getContext().region === "eu",
    new HttpLink({ uri: "http://eu-endpoint/v1/graphql" }),
    new HttpLink({ uri: "http://au-endpoint/v2/graphql" })
  )
);

优点

  • 该方法与受地球限制的区域数量成比例 - 目前。
  • 我们可以在没有反向代理路由的情况下创建和保持对已知端点的订阅。
  • 我们可以选择遍历用户访问令牌中的所有区域...
  • ...,或者我们可以选择 select 单个区域 select 由用户编辑。
  • 一旦 link 设置完成,区域端点对 UI 是完全透明的。
  • 如示例所示,这甚至有助于不同的版本。

缺点

  • 请求必须通过安静的 link 链。 (与网络通信相比,可能可以忽略不计。)