0

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

3 Answers 3

5

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

2 Comments

just incase this helps someone else there is a typo in the solution it should end #if( $foreach.hasNext ), #end #end ] } }
This might be a similar solution: stackoverflow.com/a/44320439/1357094
1

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

Comments

0

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

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.