21

I have the following Lambda function configured in AWS 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);
};

Everything works as expected (I insert an item in DynamoDB every time I call it).

I would like the dynamo table name to depend on the stage in which the lambda is deployed.

My table would be:

  • my_dynamo_table_staging for stage staging
  • my_dynamo_table_prod for stage prod

However, how do I get the name of the current stage inside the lambda ?

Edit: My Lambda is invoked by HTTP via an endpoint defined with API Gateway

1

4 Answers 4

19

If you have checked "Lambda Proxy Integration" in your Method Integration Request on API Gateway, you should receive the stage from API Gateway, as well as any stageVariable you have configured.

Here's an example of an event object from a Lambda function invoked by API Gateway configured with "Lambda Proxy Integration":

{
"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
}
Sign up to request clarification or add additional context in comments.

1 Comment

How do you access that within Lambda (java)
10

I managed it after much fiddling. Here is a walkthrough:

I assume that you have API Gateway and Lambda configured. If not, here's a good guide. You need part-1 and part-2. You can skip the end of part-2 by clicking the newly introduced button "Enable CORS" in API Gateway

Go to API Gateway.

Click here:

enter image description here

Click here:

enter image description here

Then expand Body Mapping Templates, enter application/json as content type, click the add button, then select mapping template, click edit

enter image description here

And paste the following content in "Mapping Template":

{
  "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"
}

Then click the button "Deploy API" (this is important for changes in API Gateway to take effect)

You can test by changing the Lambda function to this:

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;
    }

// ...
}

Then call your endpoint. You should have a HTTP 200 response, with the following response body:

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

Important note:
If you have a Body Mapping Template that is too simple, like this: {"stage" : "$context.stage"}, this will override the params in the request. That's why body and headers keys are present in the Body Mapping Template. If they are not, your Lambda has not access to it.

Comments

4

For those who use the serverless framework it's already implemented and they can access to event.stage without any additional configurations.

See this issue for more information.

Comments

1

You can get it from event variable. I logged my event object and got this.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.