Deepika Rajani
Deepika Rajani

Reputation: 87

Insert Multiple records in dynamodb using api gateway

How can I insert multiple rows in dynamodb using body mapping template of API gateway?

Input to my code is "xyz 1,abc 2" which has information about 2 rows to be inserted.

Only second record which is "abc 2" is getting stored, I want both records to be inserted in the table. Below is the code I have written

#set($rawAPIData = $input.path('$'))
#set ($bulk = $rawAPIData.split(","))
{
"TableName": "tablename",
#foreach( $records in $bulk)
#set ($s = $records.split(" "))
"Item": {
    "col1": {
            "S": "$s.get(0)"
    },
    "col2": {
            "S": "$s.get(1)"
    }

}
#if( $foreach.hasNext ), #end
#end
}

I'm new to this, suggestion would really help

Upvotes: 0

Views: 2303

Answers (3)

Lakshesh Girdhar
Lakshesh Girdhar

Reputation: 31

Thanks for the ideas. Loved @Gerard's approach. Incorporated both the OP's and Gerard's approach for my use case which was slightly different, I didn't want the whole splitting logic and was trying to implement it without a lambda as well.

Example Request Body:

{
  "fruit": {
    "fruitName": "Apple",
    "fruitValue": "Sweet"
  },
  "varieties": [
    {
      "varietyOrigin": "Tropical",
      "varietyName": "Mango",
      "varietyValue": "Juicy"
    },
    {
      "varietyOrigin": "Berry",
      "varietyName": "Strawberry",
      "varietyValue": "Tangy"
    }
  ]
}

Velocity Template:

{
    "RequestItems": {
        "<tablename>": [
            #foreach($item in $input.path('$.varieties'))
            {
                "PutRequest": {
                    "Item": {
                        "fruit": {
                          "S": "$util.escapeJavaScript($input.path('$.fruit.fruitName'))#$util.escapeJavaScript($input.path('$.fruit.fruitValue'))"
                        },
                        "variety": {
                          "S": "$util.escapeJavaScript($item.varietyOrigin)#$util.escapeJavaScript($item.varietyName)#$util.escapeJavaScript($item.varietyValue)"
                        }
                    }
                }
            }
            #if($foreach.hasNext),#end
            #end
        ]
    }
}

Upvotes: 1

Deepika Rajani
Deepika Rajani

Reputation: 87

I used the similar approach as @Gerand, but I solved it using lambda. Here is the working code:

 'use strict';
    const AWS = require("aws-sdk");
    const dynamodb = new AWS.DynamoDB();

exports.handler = (event, context, callback) => { 

var data=event.data;
var bulk = data.split(",");
var toSave = [];
for(var i = 0; i < bulk.length; i++) {
    var s=bulk[i].split(" ");
    var item = {
      "col1": {
            S: s[0]
    },
    "col2": {
           S: s[1]
    }
    };
    toSave.push(item);
}

var items = [];
for(var i = 0; i < toSave.length; i++) {
    items[i] = {
        PutRequest: { Item: toSave[i] }
    }
}
 var params = {
    RequestItems: {
        'table_name': items
    }
};
 dynamodb.batchWriteItem(params, function(err, data) {
        console.log("Response from DynamoDB");
        if(err) console.log(err);
        else    console.log(data);
    });
};

Upvotes: 0

Gerard
Gerard

Reputation: 111

This AWS guide shows how to use API Gateway as a proxy for DynamoDB. It's similar the approach you are trying to take. As a suggestion, it might be better have your api focus on a single row at a time, rather than splitting multiple inputs on ,. For example it would simplify your template somewhat to send requests similar to those found in the guide.

Example Request Body:

{ 
  "col1": "xyz",
  "col2": "1"
}

Template (derived from your template code):

{ 
    "TableName": "tablename",
    "Item": {
      "col1": {
          "S": "$input.path('$.col1')"
          },
      "col2": {
          "S": "$input.path('$.col2')"
         }
    }
}

However, if you want to stick to operating on multiple items, The BatchWriteItem documentation would be worth a read. Following the example, I think this should be your body template:

#set($rawAPIData = $input.path('$'))
#set ($bulk = $rawAPIData.split(","))
{
  "RequestItems": {
    "tablename": [
      #foreach($records in $bulk)
      #set ($s = $records.split(" "))
      {
        "PutRequest": {
          "Item": {
            "col1": {
               "S": "$s.get(0)"
            },
            "col2": {
              "S": "$s.get(1)"
            }
          }
        }
      }
     #if( $foreach.hasNext ), 
     #end
    ]
  }
#end
}

Upvotes: 5

Related Questions