+86 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

参考

北京 上海 天津 重庆 河北 山东 辽宁 黑龙江 吉林 甘肃 青海 河南 江苏 湖北 湖南 江西 浙江 广东 云南 福建 海南 山西 四川 陕西 贵州 安徽 广西 内蒙古 西藏 新疆 宁夏 澳门 香港 台湾