无服务器应用程序:使用AWS Lambda和API网关连续交付-第3部分:管理API网关

以前在“无服务器应用程序”中

在本系列的先前部分(第1部分,第2部分)中,我们讨论了如何测试和部署Lambda函数作为无服务器配置微服务的CI / CD管道的一部分。 今天,我们将讨论代码与Internet API网关之间缺少的链接。

据我们了解,Lambda函数是一种非常有用的方式来运行我们的代码,而不必担心基础架构真正实现它的需要。 但是,如果希望我们的代码响应来自Web的HTTP请求,则需要始终保持某种状态并侦听网络连接,以根据需要随时调用我们的功能。 例如,我们可以编写一个Web服务器来侦听请求并在调用函数时调用它们。 然后,我们将不得不将该服务器部署在负载均衡器后面的云中的某些计算机上。 那会行得通,但是从我们的角度来看,它不会那么“无服务器”,对吗? 使用Lambda函数的全部吸引力在于不必担心服务器!

输入,API网关

好了,值得庆幸的是,Lambda函数有一个很酷的表亲可以帮助我们实现这一点-API网关。 根据AWS的说法,API Gateway是一种“完全托管的服务,使开发人员可以轻松地创建,发布,维护,监视和保护各种规模的API。”基本上,API Gateway是一个托管的Web服务器,其中包括许多其他功能。 ,在路径和端点(最常见的是Lambda函数)之间建立映射。 例如,网关的配置可能会声明路径“ / user”已映射到Lambda函数“ getUser”,因此,每当客户端请求“ / user”路径时,都会调用getUser Lambda函数并返回值从我们的功能将通过HTTP发送回客户端。

但是,我们如何在生产环境中管理这种野兽呢? 当然,不要通过UI摆弄! API网关UI是探索不同配置选项的好方法,但是使用它管理我们的API可能非常麻烦且容易出错。 对于我们发布的每个端点,我们可以进行几十种配置。 让我根据个人经验告诉您,如果每次发布新端点时都必须这样做,那么很容易出错。

基础设施*是*代码

当我们编写传统的Web应用程序时,通常使用代码描述路由表。 以Express.js网站上的“ hello world”为例:

看到第6-8行吗? 路径“ /”与处理它的代码之间的关系非常清楚。 使用API​​ Gateway + Lambda作为我们的Web服务器,我们会失去这种清晰度(并可能会获得一种新的“分离度”,具体取决于您的看法)。 如果我们使用UI来配置网关,则实际上*根本没有代码*可以描述应用程序的当前版本。 那不是一个好主意。 对我们应用程序的所有更改都应该用代码描述,这样我们就可以管理版本,跟踪更改并最重要的是自动部署。

“将基础结构作为代码”的想法已经存在了一段时间:建议开发人员将其部署脚本,terraform文件和CI / CD YAML文件保留为项目版本化的源代码存储库的一部分。 对于无服务器架构,这一点变得更加重要:基础架构的配置是您正在使用的功能的组成部分。 配置新的API Gateway端点等同于向快速应用程序添加新路由。 您不敢在代码库之外执行此操作,对吗?

扩展顶点

一旦意识到从UI管理API网关是一个坏主意,我们便开始考虑我们的选择。 我们已经在使用apex(1)部署Lambda函数,因此我们所有的函数都已经在JSON文件中进行了描述。 我们不想在项目中创建更多的配置文件(每个功能已经有一个JSON文件),因此我们决定向现有文件添加更多属性,这将描述每个功能应如何连接到API网关。 看起来像这样:

使用Swagger控制API网关

API Gateway的一大特色是它支持Swagger作为一种在代码中描述API的格式。 这意味着,如果我们可以从apex JSON文件生成一个正确描述我们所需配置的swagger文件,则可以在每次部署期间更新网关以匹配我们当前的代码版本。

为了适应所有不同的配置可能性,API网关团队的成员创建了自己的Swagger扩展,例如,添加了配置API网关端点(路径)和Lambda函数之间关系的功能。 该功能的文档不是很好,因此(对我们来说)最简单的方法是使用UI创建所需的初始版本,将其导出为JSON文件,然后将其用作我们工作的基准。 当导出为Swagger扩展时,连接到Lambda函数的API Gateway端点将如下所示:

从示例中可以看到,每个端点都包含有关其如何与Lambda函数集成的信息:API网关将使用哪个IAM角色来调用该函数(“凭据”属性),哪个函数来调用(“ uri”) ),以及如何将来自HTTP请求的输入映射到Lambda函数事件(“ requestTemplates”)。

我们的部署脚本

一旦知道了必须生成的文件的结构,我们就编写了一个脚本(使用Python,但是有Java脚本的端口),该脚本在CI / CD流程中更新了API网关配置。 从总体上讲,这是脚本的作用:

  • 遍历我们的项目以查找所有相关的apex配置文件
  • 编译与API网关兼容的Swagger文件,描述我们所需的API
  • 对API网关服务进行“ PUT Rest API”调用,上传新的swagger文件
  • 对API网关服务进行“创建部署”调用。 这实际上告诉服务更新生产中的路径

为我们的无服务器应用程序实现CI / CD幸福的最后一步是将其连接到我们的部署脚本中。 我们要做的就是将以下行添加到脚本中:

现在,每当我们将提交推送到暂存分支时,就会发生以下情况:

  • 所有单元测试都运行(使用模拟lambda上下文)
  • 如果通过,我们将使用apex(1)将新版本的功能部署到lambda
  • 我们的API Gateway部署脚本运行,构建一个Swagger文件,该文件描述了我们所需的配置并更新了Gateway
  • (我们针对API网关运行了一套集成测试,本文没有介绍)
  • 大功告成!

包起来

  • 在本系列的前面部分中,我们讨论了如何为Lambda函数设置单元测试,以及如何创建用于将Lambda函数部署到生产环境的自动化工作流。
  • 在本文中,我们讨论了API Gateway如何与Lambda集成以实现用于构建Web服务器的真正的无服务器堆栈。 我们了解了AtomData开发的一种策略,用于以代码描述网关。 最后,我们展示了如何在部署过程中使用该策略自动更新API网关配置。
  • 好吧,这就是所有人! 我们在这里介绍了一些方面的内容,显示了我们如何实现无服务器应用程序的全自动部署过程。 还有很多需要讨论的地方,希望我们在以后的帖子中能够讨论到更多!

GitHub上获取 本系列中描述的解决方案的完整示例