AWS Lambda无服务开发入门——手把手教你创建一个无服务应用 :)

1,736 阅读5分钟

先决条件

  1. 创建AWS s3桶
    参考:docs.aws.amazon.com/zh_cn/Amazo…
  2. 创建Kinesis Firehose流
    参考:docs.aws.amazon.com/zh_cn/fireh…

实现功能

1、使用AWS API Gataway + AWS lambda获取访问者的Public IP ,并把它插入请求内容中,通过AWS Kinesis Firehose再传入AWS S3中

2、携带密钥对部署的该api进行访问


一、使用控制台创建 Lambda 函数

  1. 打开 AWS Lambda 控制台


    *进入控制台后请注意又上交的region,请选择选择与你业务对应的区域

  2. 选择创建函数(Create a function),进入函数创建页面


  3. 函数名称中,输入 my-function

  4. 选择运行语言,语言支持请参考官方文档,本实例采用Noda.js作为运行环境
  5. 选择 Create function。函数创建成功,进入lambda在线编译环境


  6. 把index.js中的代码替换成下面的代码(本例子中采用node.js 为了让没有接触过node.js的小伙伴能看懂,重要的语句都会添加注释)

    /**
    * 导入aws开发模块
    */
    const AWS = require('aws-sdk');
    /**
    * 为aws模块配置认证信息
    */
    AWS.config.update({
    accessKeyId: 'AKI***********PY',
    secretAccessKey: 'xle****************cIoq',
    region: 'ap-southeast-1'
    });
    /**
    * lambda核心模块,处理api请求的信息,如获取请求body,就在此模块中
    * 请求信息通过event传递,如果想要拿到例如public ip这类请求附加信息,需要在AWS API Gateway中做映射,下面会将
    */
    exports.handler = async (event) => {
    let firehose = new AWS.Firehose();
    let ip = event.context.sourceip; //public ip在API Gateway中被映射成了context.sourceip
    if(event.bodyjson){
    event.bodyjson.publicip = ip; //请求体在API Gateway中被映射成了名字为bodyjson的json
    }
    /**
    * 为firehose设置参数
    */
    let params = {
    DeliveryStreamName: 'delay-collection-a',
    Record: { /* required */
    Data: JSON.stringify(event.bodyjson)
    }
    };
    /**
    * 向firehose发送数据
    */
    firehose.putRecord(params, function(err, data) {
    if (err) console.log(err, err.stack); // an error occurred
    else console.log(data); // successful response
    });
    /**
    * 此处是为了测试,能把最终传递给firehose的数据返回给请求者
    */
    return event.bodyjson;
    };
  7. 点击保存

二、使用控制台创建AWS API Gateway

  1. 打开 AWS API Gateway 控制台


  2. 选择开始使用,进入API创建页面


  3. 选择协议中,选择REST
  4. 新建API中,选择新建API
  5. 设置中输入API名称My-API
  6. 选择创建API,API创建成功,进入API管理界面


三、使用控制台编辑My-API

  1. 选中AWS Gateway API管理界面中已经创建好的My-API
  2. 为My-API创建资源,选择操作中的创建资源,进入资源创建页面


  3. 资源名中输入my-resource,选择创建资源,资源创建成功


  4. 操作中为新创建的资源my-resource创建方法


  5. 在方法下拉框中选择POST方法


  6. 选中POST方法后,勾选旁边的勾选按钮,进入my-resource - POST - 设置 页面


  7. 集成环境中选择lambda函数
  8. lambda区域中选择第一步创建lambda中所选的region
  9. lambda函数中输任何字母,下拉框会出现你创建好的函数my-funciton,选它!选它!选它!
  10. 点击保存按钮,弹出权限确认框,点击确定,稍等片刻进入方法执行界面


  11. 在方法执行界面,选择集成请求


  12. 在集成请求页面中选择映射模板(用户请求体的信息,如请求头和publicIP就是他通过这儿获取),点击添加映射模板,并在输入框中输入application/json


  13. 在点击勾选按钮保存后弹出更改传递行为确认框,点击是,锁定此集成
  14. 点击后生成模板输入框弹出模板输入框


  15. 输入以下模板,并点击保存按钮

    ## See http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
    ## This template will pass through all parameters including path, querystring, header, stage variables, and context through to the integration endpoint via the body/payload
    #set($allParams = $input.params())
    {
    "bodyjson" : $input.json('$'),
    "params" : {
    #foreach($type in $allParams.keySet())
    #set($params = $allParams.get($type))
    "$type" : {
    #foreach($paramName in $params.keySet())
    "$paramName" : "$util.escapeJavaScript($params.get($paramName))"
    #if($foreach.hasNext),#end
    #end
    }
    #if($foreach.hasNext),#end
    #end
    },
    "stage-variables" : {
    #foreach($key in $stageVariables.keySet())
    "$key" : "$util.escapeJavaScript($stageVariables.get($key))"
    #if($foreach.hasNext),#end
    #end
    },
    "context" : {
    "account-id" : "$context.identity.accountId",
    "api-id" : "$context.apiId",
    "api-key" : "$context.identity.apiKey",
    "authorizer-principal-id" : "$context.authorizer.principalId",
    "caller" : "$context.identity.caller",
    "cognito-authentication-provider" : "$context.identity.cognitoAuthenticationProvider",
    "cognito-authentication-type" : "$context.identity.cognitoAuthenticationType",
    "cognito-identity-id" : "$context.identity.cognitoIdentityId",
    "cognito-identity-pool-id" : "$context.identity.cognitoIdentityPoolId",
    "http-method" : "$context.httpMethod",
    "stage" : "$context.stage",
    "sourceip" : "$context.identity.sourceIp",
    "user" : "$context.identity.user",
    "user-agent" : "$context.identity.userAgent",
    "user-arn" : "$context.identity.userArn",
    "request-id" : "$context.requestId",
    "resource-id" : "$context.resourceId",
    "resource-path" : "$context.resourcePath"
    }
    }

    *其中获取请求体的语句为:"bodyjson" : $input.json('$'),

    *获取public ip的语句为:"sourceip" : "$context.identity.sourceIp",


四、使用控制台测试API

  1. 回到方法执行界面,点击测试按钮,尽然测试页面


  2. 请求正文中输入以下json内容,点击测试

    {
    "test1":"abcdef",
    "test2":"abcdef"
    }
  3. 请求成功后,将返回200,并且再响应参数中多了publicip(因为使用的是aws控制台,无法获取到准确的publicip ,需要本地进行调用才能获取),证明api,编写成功


五、使用控制台部署API

  1. 在API Gateway控制台中选中API MY-API中的资源/my-resource,并点击post,进入方法执行界面


  2. 在方法执行界面点击方法请求,尽然请求设置界面,并选中需要API键 ,设置为


  3. 点击操作按钮,在下拉框中选中部署api


  4. 在弹出的部署api提示框,中,选中部署阶段下拉框,选择新阶段,在阶段名称中输入test


  5. 点击保存按钮后,跳转阶段界面,部署成功,其中调用 URL: pzoszxq868.execute-api.us-east-1.amazonaws.com/test 就是我们发布出去的api,/my-resource,就是我们调用的方法


  6. 因为我们为该api设置了访问需要密钥,所以接下来,为该api配置密钥

六、使用控制台为API配置密钥

  1. 在AWS API Gateway控制台中,选中API键,选中操作,在下拉框中选择创建API键


  2. 姓名输入框中输入:taoli , API密钥选择自动生成,d点击保存按钮,api 键生成成功


  3. 在生成的API密钥管理界面中可以查看以生成的密钥,选中API密钥,点击显示,密钥将会出现


  4. 选中使用计划,并点击创建按钮创建一个使用计划,点击按钮后将尽然使用计划创建页面


  5. 名称中填入my-test ,并根据实际需求填写限制配额的数量,点击下一步


  6. 选中添加API存储,在API下拉框中选中My-API ,在阶段下拉框中选中test,勾选按钮后,点击下一步


  7. 选中向使用计划中订阅一个API键,然后再名称中输入t会弹出已经创建好的api key taoli,选中它 ,勾选按钮后,点击完成


  8. 至此,所有api开发工作完成,下面我们将使用postman来测是我们所发布的api

七、使用Postman来测试部署的api

  1. 使用post方法对URL  pzoszxq868.execute-api.us-east-1.amazonaws.com/test/my-resource做请求
  2. 在请求之前,在request headers中加入以下访问密钥,同时加入传输类型
    x-api-key : d2M16C6EXG6t8cR9buOuPBqHesLQwER7nhelyZk4
    Content-Type: application/json
  3. 点击send,请求成功,并返回结果


  4. 通过查询s3数据,数据正常进入s3

八、参考资料

  1. AWS Lambda
  2. Amazon API Gateway