先决条件
- 创建AWS s3桶
参考:docs.aws.amazon.com/zh_cn/Amazo… - 创建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 函数
打开 AWS Lambda 控制台。
*进入控制台后请注意又上交的region,请选择选择与你业务对应的区域
选择创建函数(Create a function),进入函数创建页面
在函数名称中,输入
my-function
。- 选择运行语言,语言支持请参考官方文档,本实例采用Noda.js作为运行环境
选择 Create function。函数创建成功,进入lambda在线编译环境
把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;
};
- 点击保存
二、使用控制台创建AWS API Gateway
- 打开 AWS API Gateway 控制台。
- 选择开始使用,进入API创建页面
- 在选择协议中,选择REST
- 在新建API中,选择新建API
- 在设置中输入API名称My-API
- 选择创建API,API创建成功,进入API管理界面
三、使用控制台编辑My-API
- 选中AWS Gateway API管理界面中已经创建好的My-API
- 为My-API创建资源,选择操作中的创建资源,进入资源创建页面
- 在资源名中输入my-resource,选择创建资源,资源创建成功
- 在操作中为新创建的资源my-resource创建方法
- 在方法下拉框中选择POST方法
- 选中POST方法后,勾选旁边的勾选按钮,进入my-resource - POST - 设置 页面
- 在集成环境中选择lambda函数
- 在lambda区域中选择第一步创建lambda中所选的region
- 在lambda函数中输任何字母,下拉框会出现你创建好的函数my-funciton,选它!选它!选它!
- 点击保存按钮,弹出权限确认框,点击确定,稍等片刻进入方法执行界面
- 在方法执行界面,选择集成请求
- 在集成请求页面中选择映射模板(用户请求体的信息,如请求头和publicIP就是他通过这儿获取),点击添加映射模板,并在输入框中输入application/json
- 在点击勾选按钮保存后弹出更改传递行为确认框,点击是,锁定此集成
- 点击后生成模板输入框弹出模板输入框
输入以下模板,并点击保存按钮
## 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
- 回到方法执行界面,点击测试按钮,尽然测试页面
在请求正文中输入以下json内容,点击测试
{
"test1"
:
"abcdef"
,
"test2"
:
"abcdef"
}
- 请求成功后,将返回200,并且再响应参数中多了publicip(因为使用的是aws控制台,无法获取到准确的publicip ,需要本地进行调用才能获取),证明api,编写成功
五、使用控制台部署API
- 在API Gateway控制台中选中API MY-API中的资源/my-resource,并点击post,进入方法执行界面
- 在方法执行界面点击方法请求,尽然请求设置界面,并选中需要API键 ,设置为是
- 点击操作按钮,在下拉框中选中部署api
- 在弹出的部署api提示框,中,选中部署阶段下拉框,选择新阶段,在阶段名称中输入test
- 点击保存按钮后,跳转阶段界面,部署成功,其中调用 URL: pzoszxq868.execute-api.us-east-1.amazonaws.com/test 就是我们发布出去的api,/my-resource,就是我们调用的方法
- 因为我们为该api设置了访问需要密钥,所以接下来,为该api配置密钥
六、使用控制台为API配置密钥
- 在AWS API Gateway控制台中,选中API键,选中操作,在下拉框中选择创建API键
- 在姓名输入框中输入:taoli , API密钥选择自动生成,d点击保存按钮,api 键生成成功
- 在生成的API密钥管理界面中可以查看以生成的密钥,选中API密钥,点击显示,密钥将会出现
- 选中使用计划,并点击创建按钮创建一个使用计划,点击按钮后将尽然使用计划创建页面
- 在名称中填入my-test ,并根据实际需求填写限制和配额的数量,点击下一步
- 选中添加API存储,在API下拉框中选中My-API ,在阶段下拉框中选中test,勾选按钮后,点击下一步
- 选中向使用计划中订阅一个API键,然后再名称中输入t,会弹出已经创建好的api key taoli,选中它 ,勾选按钮后,点击完成
- 至此,所有api开发工作完成,下面我们将使用postman来测是我们所发布的api
七、使用Postman来测试部署的api
- 使用post方法对URL pzoszxq868.execute-api.us-east-1.amazonaws.com/test/my-resource做请求
- 在请求之前,在request headers中加入以下访问密钥,同时加入传输类型
x-api-key : d2M16C6EXG6t8cR9buOuPBqHesLQwER7nhelyZk4
Content-Type: application/json - 点击send,请求成功,并返回结果
- 通过查询s3数据,数据正常进入s3