如何在链接到API网关的AWS Lambda函数中获取阶段的名称

时间:2016-03-23 15:07:40

标签: amazon-web-services aws-lambda aws-api-gateway

我在AWS Lambda中配置了以下Lambda函数:

var AWS = require('aws-sdk');
var DOC = require('dynamodb-doc');
var dynamo = new DOC.DynamoDB();
exports.handler = function(event, context) {

    var item = { id: 123,
                 foo: "bar"};

    var cb = function(err, data) {
        if(err) {
            console.log(err);
            context.fail('unable to update hit at this time' + err);
        } else {
            console.log(data);
                context.done(null, data);
        }
    };

    // This doesn't work. How do I get current stage ?
    tableName = 'my_dynamo_table_' + stage;

    dynamo.putItem({TableName:tableName, Item:item}, cb);
};

一切都按预期工作(我每次调用时都会在DynamoDB中插入一个项目。)

我希望dynamo表名依赖于部署lambda的阶段。

我的表格是:

  • my_dynamo_table_staging适用于阶段staging
  • my_dynamo_table_prod适用于阶段prod

但是,如何在lambda中获取当前舞台的名称?

编辑:我的Lambda由HTTP通过API网关定义的端点调用

4 个答案:

答案 0 :(得分:10)

如果您在API网关上的方法集成请求中选中了“Lambda代理集成”,则应该从API网关以及您配置的任何stage收到stageVariable

以下是配置了“Lambda代理集成”的API网关调用的Lambda函数中的event对象示例:

{
"resource": "/resourceName",
"path": "/resourceName",
"httpMethod": "POST",
"headers": {
    "header1": "value1",
    "header2": "value2"
},
"queryStringParameters": null,
"pathParameters": null,
"stageVariables": null,
"requestContext": {
    "accountId": "123",
    "resourceId": "abc",
    "stage": "dev",
    "requestId": "456",
    "identity": {
        "cognitoIdentityPoolId": null,
        "accountId": null,
        "cognitoIdentityId": null,
        "caller": null,
        "apiKey": null,
        "sourceIp": "1.1.1.1",
        "accessKey": null,
        "cognitoAuthenticationType": null,
        "cognitoAuthenticationProvider": null,
        "userArn": null,
        "userAgent": "agent",
        "user": null
    },
    "resourcePath": "/resourceName",
    "httpMethod": "POST",
    "apiId": "abc123"
},
"body": "body here",
"isBase64Encoded": false
}

答案 1 :(得分:6)

我经过多次摆弄后设法了。这是一个演练:

我假设您已配置API网关和Lambda。如果没有,here's a good guide。你需要第一部分和第二部分。您可以通过单击新引入的按钮跳过第2部分的结尾"启用CORS"在API网关

转到API网关。

点击此处:

enter image description here

点击此处:

enter image description here

然后展开Body Mapping Templates,输入application/json作为内容类型,点击添加按钮,然后选择地图模板,点击修改

enter image description here

将以下内容粘贴到"制图模板":

{
  "body" : $input.json('$'),
  "headers": {
    #foreach($param in $input.params().header.keySet())
    "$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end

    #end  
  },
  "stage" : "$context.stage"
}

然后单击按钮" Deploy API" (这对于API网关中的更改生效很重要)

您可以通过将Lambda函数更改为:

来进行测试
var AWS = require('aws-sdk');
var DOC = require('dynamodb-doc');
var dynamo = new DOC.DynamoDB();

exports.handler = function(event, context) {
    var currentStage = event['stage'];

    if (true || !currentStage) { // Used for debugging
        context.fail('Cannot find currentStage.' + ' stage is:'+currentStage);
        return;
    }

// ...
}

然后呼叫您的终端。您应该有一个HTTP 200响应,具有以下响应正文:

{"errorMessage":"Cannot find currentStage. stage is:development"}

重要提示:
如果您的Body Mapping Template过于简单,请执行以下操作:{"stage" : "$context.stage"},这将覆盖请求中的参数。这就是body中存在headersBody Mapping Template个键的原因。如果不是,您的Lambda无法访问它。

答案 2 :(得分:1)

对于使用serverless framework已经实施的用户,他们无需任何其他配置即可访问event.stage

有关详细信息,请参阅this issue

答案 3 :(得分:0)

您可以从事件变量中获取它。我记录了事件对象并得到了它。

{  ...
    "resource": "/test"
    "stageVariables": {
        "Alias": "beta"
    }
}