首页 文章

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

提问于
浏览
8

我在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部署的阶段 .

我的 table 是:

  • my_dynamo_table_staging for stage staging

  • my_dynamo_table_prod for stage prod

但是,如何获取lambda中当前阶段的名称?

Edit :我的Lambda由HTTP通过API网关定义的 endpoints 调用

4 回答

  • 6

    如果您在API网关上的方法集成请求中检查了"Lambda Proxy Integration",则应该从API网关接收 stage ,以及您已配置的任何 stageVariable .

    以下是配置了"Lambda Proxy Integration"的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
    }
    
  • 0

    经过多次摆弄后我才设法完成了 . 这是一个演练:

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

    转到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"
    }
    

    然后单击“部署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;
        }
    
    // ...
    }
    

    然后调用您的 endpoints . 您应该有一个HTTP 200响应,具有以下响应正文:

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

    Important note:
    如果你的 Body Mapping Template 太简单了,就像这样: {"stage" : "$context.stage"} ,这将覆盖请求中的参数 . 这就是 Body Mapping Template 中存在 bodyheaders 键的原因 . 如果不是,您的Lambda无法访问它 .

  • 1

    对于那些使用serverless framework的人来说,它已经实现了,他们可以在没有任何其他配置的情况下访问 event.stage .

    有关更多信息,请参见this issue .

  • 9

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

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

相关问题