+135 410 16684Mon. - Fri. 10:00-22:00

AWS API Gateway与AWS Lambda的整合及开发/测试/生产环境的设置

AWS API Gateway与AWS Lambda的整合及开发/测试/生产环境的设置

AWS API Gateway与AWS Lambda的整合及开发/测试/生产环境的设置

AWS API Gateway与AWS Lambda的整合及开发/测试/生产环境的设置

本文不是介绍 AWS API Gateway 和 AWS Lambda的基本用法的

简单的来说,有了AWS的API Gateway和Lambda这两样东东,再加一个数据库(最好当然是用AWS DynamoDB啦,或者AWS EC2上装mysql,不用AWS也可以,但是访问速度可能会有一定影响,毕竟如果都用AWS的话算是走内网会快一些?!),不需要任何网络应用的框架你就能开发出非常RESTful的API了,简直是中小型公司提高开发效率的神器!

再简单的来说,API Gateway给你提供一个URL,当这个url被访问的时候,就会调用你设置的某个Lambda函数,这个函数执行完了之后就会返回你设定的数据。也就是说,以前你在服务器端收到一个请求,然后“做一堆事”完了之后发出响应Response的这个“做一堆事”和Response,写在一个Lambda函数里就可以了。

通常如果浏览器端使用ajax访问这个URL都会存在跨域的问题,API Gateway当然很贴心的提供了enable CORS选项!

AWS Lambda目前支持python,JAVA,NodeJS。这个Lambda函数呢,只是叫Lambda而已,实际写起来跟函数式编程也没有太大的关系,以前怎么写现在也还是一样的写…神奇的是,Lambda之间可以相互调用,另外除了API Gateway之外,很多别的跟API Gateway无关的事件event也可以作为trigger(比如当DynamoDB的某个Table新增一条用户记录的时候,调用一个名称为sendWelcomeEmailToUser()的Lambda函数,给用户发欢迎邮件

那么如何设置AWS API Gateway和AWS Lambda来实现开发/测试/生产环境的需求呢?难道要同一个功能的API建3个、同一个功能的lambda建3个?!


以下所有内容都是在AWS的WEB UI中进行设置的。(除了在UI中设置,还可以写Shell脚本去批量执行这些设置,当然啦,这个我还没学会…)

哦,忘了说…首先你要有个…API,然后你还要有个Lambda。
假设:

  • API endpoint是 /stageTest,方法是GET
  • Lambda名为stageTest。 (endpoint的名字和lambda名字可以不同…原谅我是取名无能星人…)

DEV / QA / PROD 环境的设置

  1. 为API Gateway创建不同的stage^1,假设创建了3个分别是dev,qa,prod。

    设置了stage之后你的api endpoin看起来大概长这样:

    • .execute-api..amazonaws.com/dev
    • .execute-api..amazonaws.com/qa
    • .execute-api..amazonaws.com/prod
  2. 为每个的Stage设置stageVariables^2,假设为每个Stage都设置了一个名为env的变量
    • dev这个stage中env变量的值为DEV
    • qa这个stage中env变量的值为QA
    • prod这个stage中env变量的值为PROD
  3. Lambda stageTest()函数创建不同的alias^3,假设创建了3个分别是DEV,QA,PROD,分别指向不同的版本。
    • 在每次deploy后,都是$LATEST版本,点action>publish new version发布不同的版本
    • 建议DEV指向$LATEST版本,QA和PROD指向其他稳定的版本
    • 为Lambda创建了alias之后,其实这个lambda访问的名称就有了以下四种:stageTeststageTest:DEVstageTest:QAstageTest:PROD,其中stageTest永远指向$LATEST版本,其他指向之前设置的各个版本
  4. 整合API /stageTest 的GET方法与Lambda stageTest()^5
    • 首先在API Gateway的界面中设置每个API方法的Integration Request:Integration Type选择Lambda Function;Lambda Function填stageTest:${stageVariables.env}${stageVariables.env}就是第2步中,设置的变量。
    • 设置Lambda Function名称的时候一定要记得点旁边的√保存,保存的时候,AWS会弹出一个对话框,需要给函数加上权限才能使用stageVariables变量。加的时候记得要执行三次命令,也就是在AWS给出的命令的对应的位置改成 stageTest:DEVstageTest:QAstageTest:PROD 每个执行一次。
    • 执行以上命令之前,你必须:
      • 安装AWS CLI
      • 执行命令aws configure,填写你的AWS ID和key,设施default region为你的lambda function所在的region

那么,问题又来了…

  • 如果你已经部署了很多lambda和api却没有使用stage的话…似乎是不太可能手动去AWS界面上一个一个设置的
  • 就算你已经在使用stage了,似乎也不太可能每次都手动去AWS界面上一个一个deploy最新的版本以及改变alias指向的版本的…

这个时候,你就必须研究AWS CLI,然后写shell以及借助其他工具来进行自动化部署了…

其他参考:

AWS API Gateway Mapping Template 获取IP, header等

适用场景

在配合API Gateway和Lambda来搭建RESTful API时,Lambda获取的payload并非通常服务器端获取的一个request对象,lambda获取到的payload并不包含 request header的内容,而只有request body的内容。

header中的部分内容可以通过API Gateway提供的变量从mapping template中获取。可以获取的内容包括IP, http方法,路由参数,query等,具体可以看文档^1

设置方法

按照理论来说,AWS设置可以通过界面设置的都可以通过脚本来设置。下面只介绍在界面中的设置:

  1. 在API Gateway界面中选中具体的api方法,点击右侧的Intergration Request
  2. 在底部点击Mapping Templates
  3. 点击Add Mapping Template,输入application/json,点击√进行确认
  4. 在右侧新出现的区域,点击编辑按钮(铅笔图标),输入需要的变量即可,例如要获取ip:
    {
    “body”: $input.json(‘$’),
    “source_ip” : “$context.identity.sourceIp”,
    }

其中$input.json('$')是请求时客户端发来的body

response header和cookie

在配合使用lambda和API gateway的时候,header和cookie是非常令人头疼的问题…
lambda返回的内容,只是response body,因此设置header要在api gateway中进行,并且也是有一些限制的:

  1. 在API Gateway界面中选中具体的api方法,点击右侧的Method Response
  2. 展开HTTP Status,点击Add Header,添加一个header。

    注意:可以添加多个Header,但这些header不能同名,这也就意味着,只能有一个Set-Cookie,只能添加一个cookie

  3. 完成以上步骤后,返回第一步所在的页面,点击Integration Response,点击三角展开,会看到Header Mappings
  4. 在对应的位置编辑mapping value
    • 如果想使用lambda返回的数据,设置为integration.response.body.KEY
    • 如果不是使用lambda(即把gateway用作代理),而是使用实际服务器返回的header,设置为integration.response.header.KEY

参考