前端模式的后端

在这篇博客文章中,我们描述了如何通过实现前端后端模式并在 微服务 引发域聚合中发生突变的事件时提供实时可视化更新,来改善用户界面 (UI) 上的最终用户 体验。

提出的解决方案结合了两种模式:1) 前端 后端 (BFF) 模式,即应用程序的 每种用户体验都有一个 后端 ,而不是只有一个通用 API 后 端;2) 发布 者-订阅者 (发布 /订阅)模式,其中微服务异步地向多个感兴趣的消费者发布事件,而无需将发送者与接收者耦合。结合使用这两种模式后,前端客户端可以加载用户界面就绪的数据投影,并使用 事件驱动 的 通知刷新用户界面,从而为最终用户提供高性能的近乎实时的体验。

为了向 REST GraphQL API 开发人员解释解决方案,我们提供了两张针对每种 API 技术的相似架构图。

BFF 图案

根据 山姆·纽曼 的说法 ,前端后端(BFF)模式是指每个用户体验都有一个后端,而不是只有一个通用 API 后端。

传统上,容纳多种用户界面的方法是提供单一的服务器端 API,并随着时间的推移根据需要添加更多功能,以支持新的移动交互类型。这种方法可能会带来以下挑战:

  1. 移动设备进行更少的调用,并且希望显示与台式机设备不同(可能更少)的数据,这意味着 API 后端需要额外的功能来支持移动接口。
  2. 现代应用程序 用户 界面越来越多地采用反应式策略向最终用户提供实时反馈(例如通过 WebSoc kets ),不同的设备可能会实现不同的技术堆栈来支持它。
  3. 顾名思义,API 后端为多个面向用户的应用程序提供功能——这意味着在推出新的交付时,由于对同一个可部署工件进行了许多更改,单个 API 后端可能会成为瓶颈。

为了应对这些挑战,山姆 建议 你应该将面向用户的应用程序视为两个组件:一个位于边界之外的客户端应用程序,另一个位于边界内的服务器端组件(BFF)。据他介绍,BFF与特定的用户体验紧密相连,通常由与用户界面相同的团队进行维护,因此可以更轻松地根据用户界面的要求定义和调整API,同时还简化了排列客户端和服务器组件版本的过程。

在山姆的建议下,像Netflix这样的公司已经采用了BFF模式,他们的安卓团队 无缝交换了Netflix安卓应用程序的API后端 ,使他们能够在更高的审查和可观察性以及与Netflix微服务生态系统的集成的情况下使用其终端。

亚马逊云科技 上事件驱动的 BFF 的组件

假设你已经有了 事件驱动的架构 ,无论事件是由多个 微服务 还是单个单体生成的,那么你已经有足够的空间开始为每种最终用户体验构建解耦的事件驱动后端forFrontends (BFF)。

下图显示了架构及其消息流的高级视图。右边代表域名发布商,每个域名发行商都有自己的特定域名聚合数据库;左边是BFF订阅者,每个都有自己的用户体验特定的投影数据库。中间有一条事件总线传播域名状态的变化,允许发布商和订阅者保持分离。

Figure 1. Message flow diagram.

图 1。消息流程图。

除了以下常用组件外,本博客文章中描述的事件驱动型 BFF 解决方案还依赖于特定技术的 API:

  • 用于存储域投影表的 NoSQL 数据库 ,它还支持 变更数据捕获 (CDC)。在这里,我们使用 亚马逊 Dynamo DB,这是一种快速、灵活的 NoSQL 数据库服务,可在任何规模下实现个位数毫秒的性能。
  • 一个 计算层 ,用于处理请求并将CDC流与API集成。在这里,我们使用的是 亚马逊云科技 L am bda,这是一种无服务器、事件驱动的计算服务,可让您在不考虑服务器或集群的情况下运行代码。
  • 保护 API 的身份验证和授权机制。在这里,我们使用 Amazon Cognito ,这是一项用于用户注册、登录和访问控制的简单而安全的服务。

使用 API 网关构建事件驱动的 REST BFF

Amazon API Gateway 是一项完全托管的服务,可让开发人员轻松创建、发布、维护、监控和保护任何规模的 API。API 充当应用程序从后端服务访问数据、业务逻辑或功能的 “前门”。使用 API Gateway ,你可以创建支持实时双向通信应用程序的 RESTful AP I 和 WebSocket API

以下架构图使用 域驱动设计 (DDD) 概念描述了如何利用 API Gateway WebSocket AP I 为最终用户创建事件驱动的用户界面。有关此图表的 PDF 版本,请参阅 此链接

Figure 2. Diagram of RESTful BFF using API Gateway.

图 2。使用 API 网关的 RESTful BFF 示意图。

实施步骤:

  1. 使用专门构建的 BFF 事件使用者从您的应用程序中捕获事件。它们负责更新 Am azon DynamoDB 中的非标准化数据预测以供前端使用。
  2. 在加载界面时,前端客户端使用 亚马逊 Cognito 进行身份验证,然后通过调用使用亚马逊 API Gateway 构建的 BFF AP I 来查询数据。 然后在 DynamoDB 中提取数据,可以直接通过 API 网关获取,也可以通过使用 亚马逊云科技 Lambda 构建的 BFF 查询处理程序获取。
  3. 前端客户端通过连接到 API Gateway 提供的 BFF WebSocket 端点来订阅任何后续的数据更改,这会触发 “连接的客户端” 表的更新。
  4. 使用 BFF 事件使用器继续使用和处理应用程序中的所有相关事件。这些消费者不断实时更新BFF数据库中的非标准 前端数据视图。
  5. 使用 Amazon DynamoDB Streams 订阅 由 BFF 数据库中的数据变化产生的所有事件,然后 在 亚马逊云科技 Lambda 中 注册 触发器,以便在检测到新的流记录时异步调用 BFF 流处理程序 Lambda 函数。
  6. 然后,你的 BFF 流处理程序会向连接到 API Gateway 的 WebSockets 的客户端推送通知。
  7. 当前端客户端收到来自 API Gateway 的变更通知时,他们可以刷新 UI 内容。

使用 AppSync 构建事件驱动的 GraphQL BFF

我们看到越来越多的组织选择使用 GraphQL 构建 API,因为前端开发人员能够使用单个 GraphQL 端点查询多个数据库、微服务和 API,从而帮助他们更快地开发应用程序。

亚马逊云科技 AppSync 是一项完全托管的服务,通过处理安全连接到亚马逊 DynamoD B、 亚马逊云科技 Lambd a 等数据源的繁重工作,可以轻松开发 GraphQL API。 部署后, 亚马逊云科技 AppSync 会自动向上和向下扩展您的 GraphQL API 执行引擎以满足 API 请求量。 此外, AppSync 还 添加了 缓存 以提高性能,支持保持离线客户端同步的客户端 数据存储 ,并支持通过 WebSockets 的透明订阅进行实时更新。

以下架构图使用 域驱动设计 (DDD) 概念描述了如何利用 AppSync 订阅为最终用户创建事件驱动的用户界面。有关此图表的 PDF 版本,请参阅 此链接

Figure 3. Diagram of GraphQL BFF using AppSync.

图 3。使用 AppSync 的 GraphQL BFF 示意图。

实施步骤:

  1. 使用专门构建的 BFF 事件使用者从您的应用程序中捕获事件。它们负责在 Am azon DynamoDB 中保持非标准化数据视图以供前端使用。
  2. 在加载界面时,前端客户端 使用 Amazon Cognito 进行身份验证 ,然后通过调用 亚马逊云科技 AppSync 构建的 BFF API 使用 GraphQL 查询数据。 然后在 DynamoDB 中提取数据,可以直接通过 亚马逊云科技 AppSync 获取,也可以通过使用 亚马逊云科技 Lambda 构建的 BFF 查询处理程序获取。
  3. 前端客户使用通过 WebS ock ets 订阅 的 亚马逊云科技 AppSync 订阅来订阅任何后续数据更改。
  4. 使用 BFF 事件使用器继续使用和处理应用程序中的所有相关事件。这些消费者不断实时 更新 BF F数据库中的非 标准化 前端数据视图。
  5. 使用 Amazon DynamoDB Streams 订阅 由 BFF 数据库中的数据变化产生的所有事件,然后 在 亚马逊云科技 Lambda 中 注册 触发器,以便在检测到新的流记录时异步调用 BFF 流处理程序 Lambda 函数。
  6. 然后,您的 BFF 流处理程序会调用 亚马逊云科技 AppSync GraphQL 架构上的空 突变 ,该变更是 专门为强制触发订阅而创建的,从而向客户发送通知。
  7. 当前端客户收到来自 亚马逊云科技 AppSync 的变更通知时,他们可以刷新用户界面内容。
    亚马逊云科技 AppSync 提供了简化的 WebSockets 体验,包括实时数据、连接、可扩展性、扇出和广播,所有这些都由 亚马逊云科技 AppSync 服务处理,使开发人员能够专注于应用程序用例和需求,而不必处理大规模管理 WebSockets 连接所需的复杂基础设施。

步骤 6 中的 亚马逊云科技 Lambda 流处理函数是由向亚马逊 DynamoDB 表中插入新项目触发的。它读取这些项目并更新 亚马逊云科技 AppSync,提醒它注意新数据。 此代码的示例以 node.js 编写,可 在 GitHub 上找到,作为在 多区域设置中 部署 亚马逊云科技 AppSync 的 A WS 示例的一部分。 主要函数已提取出来,解释如下。

以下代码显示了 Lambda 函数的入口点。它接收来自 DynamoDB 的事件,该事件由流中的新数据触发。对于每个新条目,如果是已插入(而不是更新或删除)的数据,它将解析数据并调用 executeMut ation 函数。

exports.handler = async(event) => {

  for (let record of event.Records) {
    switch (record.eventName) {
    
      case 'INSERT':
        // Grab the data we need from stream...
        let id = record.dynamodb.Keys.id.S;
        let name = record.dynamodb.NewImage.item.S;
        // ... and then execute the publish mutation
        await executeMutation(id, name);
        break;
        
      default:
        break;
    }
  }
  
  return { message: `Finished processing ${event.Records.length} records` }
}

以下代码是 exec uteMutation 函数,它使用从 DynamoDB 流接收的新数据对 亚马逊云科技 AppSync 进行更改。它使用第三方库 Axios (适用于 node.js 的基于承诺的 HTTP 客户端)连接到 AppSync API 端点并发布突变。

const executeMutation = async(id, name) => {

  const mutation = {
    query: print(publishItem),
    variables: {
      name: name,
      id: id,
    },
  };

  try {
  
    let response = await axios({
      url: process.env.AppSyncAPIEndpoint,
      method: 'post',
      headers: {
        'x-api-key': process.env.AppSyncAPIKey
      },
      data: JSON.stringify(mutation)
    });
    
  } catch (error) {
    throw error;
  }
};

突变是使用以下 GQL 代码生成的:

const publishItem = gql`
  mutation PublishMutation($name: String!, $id: ID!) {
    publishItemsModel(input: {id: $id, item: $name}) {
      id
      item
    }
  }
`

结论

BFF 模式是指每个用户体验都有一个后端,而不是只有一个通用 API 后端。

通过在事件驱动架构中实现 BFF 模式,当微服务引发域聚合变异事件时,您可以提供近乎实时的可视化更新,从而改善用户界面上的最终用户体验。

在这篇博客文章中,我们解释了开发人员如何将 BFF 模式应用到他们的 REST GraphQL API 中,以加载支持界面的数据投影,并使用事件驱动的通知刷新用户界面。

您可以在此处下载亚马逊 API Gateway 的 PDF 格式的详细参考架构, 在此处 下载 亚马逊云科技 AppSync 的详细参考架构。

作者简介:

Aaron Sempf

Aaron Sempf 是全球系统集成商团队的全球首席合作伙伴解决方案架构师。在不与 亚马逊云科技 GSI 合作伙伴合作时,可以发现他正在为自主机器人、物联网设备和分布式解决方案编写原型。

Jamila Jamilov

a Jamilova Jamilova 是一名初创企业解决方案架构师,帮助英国的金融科技、HCLS 和 SaaS 初创企业在 亚马逊云科技 云上使用尖端技术和服务构建产品。她的专业领域是大数据和物联网 (IoT)。在业余时间,她弹钢琴,跑步,喜欢玩赛车。

Jorge Fonseca

Jorge 是一名解决方案架构师,在 IT 领域拥有 20 多年,拥有 2 个硕士学位和所有 亚马逊云科技 认证。在 亚马逊云科技,他通过将复杂的挑战转化为面向技术和业务受众的可操作路线图,帮助客户完成云之旅。

拉尔夫·理查兹

·拉尔夫是位于伦敦的亚马逊网络服务的解决方案架构师。他作为技术顾问与企业软件和SaaS客户合作,帮助他们在云端实现业务目标。他还专门研究容器技术,对使用微服务方法构建现代应用程序有着浓厚的兴趣。工作之余,他喜欢摄影、阅读和探索公路旅行中的新地方。


*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。