自 2015 年成立以来,GraphQL 的受欢迎程度迅速上升,并且围绕它发展了一个庞大的社区。

[Alt](https://res.cloudinary.com/practicaldev/image/fetch/s--b65ESjM5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/i/jkg2kahaak4lhgpnnewy.jpeg)

AppSync 是一种完全托管的AWS 无服务器服务,用于实时数据查询、同步和通信。在AppSync中,AWS 提供了 GraphQL 即服务产品,可以轻松在云中构建可扩展且有弹性的 GraphQL API。您不需要自己运行任何服务器。只需配置您的 GraphQL 解析器,您就会拥有一个可以扩展到数百万用户并提供开箱即用的多可用区冗余的 GraphQL API。

简单地说,AppSync 之于 GraphQL 就像 API Gateway 之于 REST API。

最近几个月,我一直在广泛使用 AppSync,并且越来越喜欢它。它不仅可以轻松构建可扩展的 GraphQL API,还可以简化 API Gateway 中的困难任务。

在所有其他条件相同的情况下,以下是我应该考虑在下一个项目中使用 AppSync 而不是 API Gateway 的五个主要原因。

1\。基于 Cognito 组的授权

想象一下,您正在构建一个 CMS 应用程序,超级管理员可以在其中创建大学并指定可以管理自己个人资料的大学管理员。

要实现这一点,您可以使用 Cognito 用户组来控制对不同 API 端点的访问。例如

  • POST /universities只能由Admin组中的用户访问,以创建新大学并设置其初始配置文件。

  • Post /university/my只能由University组中的用户访问以更新他们的个人资料。

这可以通过 API Gateway 实现,但正如您从官方指南中看到的那样,这需要做很多工作:

1.添加用户组

2.为每个组分配一个IAM角色,控制组内用户可以访问哪些端点

  1. 为组分配优先级,因为一个用户可以属于多个组,并且您需要解析为一个 IAM 角色

  2. 当您向 API Gateway 发送请求时,从 Cognito 提交 ID 令牌

  3. 编写一个自定义的 Lambda 授权函数(没错,你不能使用 Cognito 授权!)根据 ID 令牌生成正确的策略

情况很复杂。

相比之下,这就是我在 AppSync 中实现基于组的授权所需的全部内容。

[Alt](https://res.cloudinary.com/practicaldev/image/fetch/s--duxyB6O---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev -to -uploads.s3.amazonaws.com/i/e1fry9qw4dpshfl3q5tx.jpeg)

它毫不费力且不言自明。

在我们的指南中了解有关 AWS 无服务器的更多信息:AWS Step Functions – 限制、用例、最佳实践

2\。请求和响应验证

API Gateway 被低估的功能之一是它可以为您执行请求验证。未通过模式验证的请求不会产生费用。这是保护自己免受天真地向您抛出垃圾请求的恶意攻击者的好方法。但是,当然,这并不能阻止重放攻击。

但是,不支持响应验证。即使您可以为端点配置响应模型,它也仅用于文档目的。您必须在应用程序代码中实现响应验证。middy等库通过验证器中间件对此提供支持。

如果没有响应验证,很容易意外返回比您预期更多的数据。

例如,如果您在User表中记录了用户的 dob,您应该将其返回给查看该用户个人资料的每个人还是只返回给用户本人?用户的电子邮件呢?

您可能不会在 UI 中显示这些个人数据,但它仍会出现在 HTTP 响应中。任何拥有 HTTP 代理的人都可以窥探数据。

使用 API Gateway 完成请求和响应验证是完全可能的。但这很费力,而且 API Gateway 不会因为犯错(或只是忘记做)而让您松懈。

现在,看看我需要在 AppSync 中做什么。

[Alt](https://res.cloudinary.com/practicaldev/image/fetch/s--BKra7olp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/i/ncsv7vfy05gj9gsiaxrs.jpeg)

这一切都在 GraphQL 类型定义中!不涉及额外的工作。

类型定义中未包含的内容将不会返回。这是 GraphQL 工作方式所固有的。这使您有更多时间考虑您的域以及如何最好地使用类型对其进行建模,而不必花时间担心请求和响应验证的机制。

3\。可扩展的 WebSocket

回到 re:invent 2018,API Gateway宣布支持 WebSockets。但再一次,它绝不容易使用。

作为应用程序开发人员,您必须维护 WebSocket 连接到用户或组的映射。为此,您可以实现处理 API GatewayonConnectonDisconnect事件的 Lambda 函数。当您需要向特定用户发送消息时,您必须找到他们的连接 ID 并调用 API Gateway 管理 API 以一次发送一条消息

[Alt](https://res.cloudinary.com/practicaldev/image/fetch/s--FkaDYOl7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/i/e77g39fug9vks7932md8.jpeg)

同样,这是一个非常低级的结构,并且将很多繁重的工作放在了您的肩上。而且实施群聊或广播的成本效率非常低。

想象一下,如果您正在构建一个体育流媒体应用程序,并且您想通知所有观看巴塞罗那对阵皇家马德里的人进球已进。如果您有 100 万观众观看那场比赛,那么这意味着:

  • 百万次从您的 DynamoDB 表中读取

  • 对 API Gateway 管理 API 的一百万个 API 请求

也就是说,如果您的 Lambda 函数在此之前没有超时,并且您在此过程中没有受到限制!

也就是说,API Gateway 的 WebSockets 适用于那些需要一次向一小组用户发送消息的简单用例。例如,1-2-1 私人聊天,甚至可以限制群组规模的群聊。

但是,实现起来仍然相当费力,并且迫使您花费大量时间在套接字管理的机制(“如何”)上,而不是要发送什么消息(“什么”)。

相比之下,AppSync 订阅使用起来轻而易举。

[Alt](https://res.cloudinary.com/practicaldev/image/fetch/s--GAQqHiAT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/i/dngtpm3rv2mclry4hlf6.jpeg)

自从 AppSync宣布支持纯 WebSockets以来,它现在可以支持数百万连接的客户端。所有这些,您不必自己管理任何连接!

这并不是说 AppSync 订阅没有它自己的粗糙边缘。但更多内容在另一篇文章中。

4\。自动化 API 文档

我们之前谈到了请求和响应模型。为端点配置模型后,它们将包含在 API 文档中,您可以从 API Gateway 控制台导出该文档。

[Alt](https://res.cloudinary.com/practicaldev/image/fetch/s--ndGQfStv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/i/yprx5kxjzfu8z4cp7vil.jpeg)

这也可以通过 AWS CLI 或 AWS 开发工具包来完成。但就像 API Gateway 的许多其他事情一样,它并不像您想要的那么简单......

合约优先开发呢?这是一种越来越流行的做法,团队在开始实施 API 端点之前首先进行协作并就 API 合同达成一致。

API Gateway 允许您使用 openAPI 规范创建 API。

[Alt](https://res.cloudinary.com/practicaldev/image/fetch/s--qOPVgitB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/i/sss0egyls14pqcxjf7cw.jpeg)

但是,我们使用 API Gateway 和 Lambda 构建 API 的许多工具都不支持此流程 — e.g.无服务器框架或 SAM。

使用 GraphQL,合约优先的开发是必然的。从定义类型、查询和突变开始,人们构建 GraphQL API 的方式与生俱来。生成的.graphql规范也是自记录的!

5.与 DynamoDB/ElasticSearch/RDS 集成

在撰写本文时,AppSync 已与 DynamoDB、Lambda、RDS、ElasticSearch 和 HTTP 直接(即,无需通过 Lambda 函数代理)集成。

在与其他 AWS 服务的直接集成数量方面,API Gateway 胜出。这里没有竞争,因为 API Gateway 可以与几乎所有其他 AWS 服务集成。

[Alt](https://res.cloudinary.com/practicaldev/image/fetch/s--vUSoXzpA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/i/dksgzq5jwum188poyi46.jpeg)

在这两种情况下,API Gateway 和 AppSync 都使用Apache VTL作为这些服务集成的脚本语言。

但是,就“如何”与其他服务集成而言,两者之间的差异令人吃惊。

根据我在无服务器框架的serverless-apigateway-service-proxy插件上工作的经验,API Gateway 服务代理有多种约定。有时,它通过对服务 REST API 的签名 HTTP 请求与其他 AWS 服务集成。其他时候您必须编写自定义 VTL 代码。

在每种情况下,配置都相当复杂,因为您必须配置很多不同的东西。这里是一个很好的例子,以防你想知道。

使用 AppSync,您总是需要编写一些 VTL,这不是每个人都喜欢的。但幸运的是,在实践中,这主要是在 VTL 模板中填写您的位的情况。官方文档做得很好,提供了很多示例,您可以将其复制并粘贴到您的解析器中。

[Alt](https://res.cloudinary.com/practicaldev/image/fetch/s--eCR8mibl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/i/cj380q59o0nkbxv8x2kc.jpeg)

最重要的是,AppSync 解析器内置支持为 DynamoDB 的QueryScan操作生成分页令牌。这混淆了将前一个查询中的LastEvaluatedKey作为下一个查询的ExclusiveStartKey传递的内部机制。这是许多人犯错的地方,并且不小心将他们的客户端-服务器通信与 DynamoDB 中的实现细节结合在一起。您可以在此处阅读有关如何正确进行分页的更多信息。

总体而言,我发现虽然 AppSync 的直接服务集成数量有限,但它所具有的文档更好,并且更易于使用。

总结

就是这样,以下是考虑在您的下一个项目中使用 AppSync 而不是 API Gateway 的五个光荣理由:

  • 它原生支持基于 Cognito 组的授权

  • 请求和响应验证内置于 GraphQL 的工作方式中

  • 它的 WebSockets 实现既易于使用又具有高度可扩展性

  • 它适用于合同优先的开发,并且不需要额外的过程来生成 API 文档

  • 它与 DynamoDB 的服务集成更易于使用,并提供其他增值功能,例如分页令牌

总的来说,我发现我在这里列出的所有内容都可以通过 API Gateway 来实现。但在任何情况下,它都比使用 AppSync 需要更多的努力。

在最近的一个客户项目中,当我们处理敏感的个人数据时,我需要为每个 API 端点可靠地实现基于 Cognito 组的授权以及请求和响应验证。

经过一周的辛苦和失败后,我决定转向 AppSync。在几个小时内,我就能够实现我们需要的一切,甚至更多。结果,我能够让项目重回正轨,并专注于解决手头的业务问题。

简单地说,AppSync 之于 GraphQL 就像 API Gateway 之于 REST API。

和更多。

了解AWS Lambda 监控使用 Lumigo 有多么简单。


最初发表于https://lumigo.io。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐