Skip to content

Instantly share code, notes, and snippets.

@jtsaito
Last active January 31, 2018 18:33
Show Gist options
  • Save jtsaito/24c66722cdb826307356 to your computer and use it in GitHub Desktop.
Save jtsaito/24c66722cdb826307356 to your computer and use it in GitHub Desktop.
AWS DyndamoDB and Lambda

This code example briefly describes how to store data to and retrieve data from DynamoDB using two AWS Lambdas. In this example we assume a DynamoDB tale test-can-learn with String key user_uuid in region eu-west-1. As a bonus, we show how to make the read access available as RESTful resource with AWS' API Gateway.

1. Setup Lambdas

Skip Lambda templates and craete the Lambdas custom. Then assign the Basic with DynamoDB role to the Lambda.

2. Lambda writing to DynamoDB

var AWS = require('aws-sdk');
var dynamodb = new AWS.DynamoDB({
  region: 'eu-west-1'
});

exports.handler = function(event, context) {
  var can_learn = JSON.stringify(event.can_learn);

  dynamodb.putItem({
    "TableName": "test-can-learn",
    "Item": {
      "user_uuid": {
        "S": event.user_uuid
      },
      "can_learn": {
        "SS": event.can_learn
      }
    }
  }, function(err, data) {
    if (err) {
      context.fail('ERROR: Dynamo failed: ' + err);
    } else {
      console.log('Dynamo Success: ' + JSON.stringify(data, null, '  '));
      context.succeed('SUCCESS');
    }
  });
}

Test with the following test event.

{
  "user_uuid": "de051ff6ea585640a3afe985daba9e90",
  "can_learn": ["POL", "ENG", "NLD"]
}

3. Lambda reading from DynamoDB

var AWS = require('aws-sdk');
var dynamodb = new AWS.DynamoDB({
  region: 'eu-west-1'
});

exports.handler = function(event, context) {
  dynamodb.getItem({
    "TableName": "test-can-learn",
    "Key": {
      "user_uuid": {
        "S": event.user_uuid
      }
    }

  }, function(err, data) {
    if (err) {
      context.fail('ERROR: Dynamo failed: ' + err);
    } else {
      console.log('Dynamo Success: ' + JSON.stringify(data, null, '  '));
      context.succeed(data.Item.can_learn.SS);
    }
  });
}

Test with the following test event.

{
  "user_uuid": "de051ff6ea585640a3afe985daba9e90"
}

This returns the following result. (Note that DynamoDB does not guarantee the order of lists.)

[
  "ENG",
  "NLD",
  "POL"
]

4. Bounus: Publishing the Lambda by AWS API Gateway

In order to make the lambda for reading from DynamoDB callable as RESTful resource, we make it available by API Gateway using the AWS console. To that end we create a new API Gateway "can-learn" with GET resource users. (We set authorization to public for testing and use IAM roles later on.) We connect the resource to the lambda simply by selecting it from a dropdown. Next, we need to map the REST query parameter (user_uuid) to the event object handled in the lambda. This is done in the resource's Integration Request section. Here add a content-type application/json. Finally, paste the following mapping template (this is actually Swagger).

#set($inputRoot = $input.path('$'))
 {
  "user_uuid" : "$input.params('user_uuid')"
 }

The API Gateway's users resource can now be tested (after creating a test stage) by using the displayed resource URL with query parameter user_uuid=de051ff6ea585640a3afe985daba9e90.

Similarly, for writing to the resource, we can create a POST method (e.g. in a nested resource can_learn/{user}). The method uses the following Integration Test's Mapping Template.

#set($inputRoot = $input.path('$'))
 {
  "user_uuid" : "$input.params('user')",
  "can_learn": $input.json("$.can_learn")
 }

Note that the user_uuid is taken from the resource path and the can_learn attribute from the JSON body. Furthermore, the quotes in the .json() method require particular attention: this will work with double quotes only.

Below is a cURL query testing the resource (replace <YOUR-RESOURCE-URL-HERE> with your particular url).

curl -H "Content-Type: application/json" -X POST -d "{\"can_learn\":[\"FRA\", "BRA"]}" https://<YOUR-RESOURCE-URL-HERE>.api.eu-west-1.amazonaws.com/test/can-learn/fooxooo

This will store the user_uuid key with value fooxooo and can_learn with value { "BRA", "FRA" } in DynamoDB.

Resources

  1. Lambda context object
  2. DynamoDB API Documentation for PutItem, useful for understanding attribute hash format
  3. Tutorial by some guy on the internet
  4. Useful example for using API Gateway's Input Templates
  5. API Gateway Mapping Template Reference
  6. Useful use cases for authorizing Lambda calls. This is not directly covered by the examples above.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment