Search code examples
node.jsamazon-web-servicesaws-lambdaaws-step-functions

How to put array in Dynamo Db using step function


I have a lambda function that passes the input values to step function. Below is the input that Step function is receiving which is good. My step function is suppose to write these fields to Dynamo table. I am having issues with ENTITIES in step function. I simply want to take entity array as it from input and put in dynamo table. I have tried using items path & array parameter but that failed. Any help will be appreciated. // Input to Step function

{
  "CLIENT_ID": "fa1188",
  "CLIENT_NAME": "Country Village 1188",
  "SOURCE_IDENTIFIER": "abc-123-Country_Village 1188",
  "ENTITIES": {
    "L": [
      {
        "S": "Test1"
      },
      {
        "S": "Test8"
      },
      {
        "S": "Test8"
      }
    ]
  },
  "CREATED_TIMESTAMP": "1597436891604"
}

// Step function

{
  "Comment": "PutItem into DynamoDB",
  "StartAt": "1st",
  "States": {
    "1st": {
  "Type": "Task",
  "Resource": "arn:aws:states:::dynamodb:putItem",
  "Parameters": {
    "TableName": "CLIENTS",
    "Item": {
      "CLIENT_ID": {
        "S.$": "$.CLIENT_ID"
      },
      "CLIENT_NAME": {
        "S.$": "$.CLIENT_NAME"
      },
      "SOURCE_IDENTIFIER": {
        "S.$": "$.SOURCE_IDENTIFIER"
      },
    "CREATED_TIMESTAMP": {
        "S.$": "$.CREATED_TIMESTAMP"
    },
     **"ENTITIES": {         
        "S.$":"$.ENTITIES.L"
     }**
    }
    },
    "End":true,
    "ResultPath":"$.DynamoDB"
    }
  }
}

I am able to store all other value saved other than entity.I want Entity column in Dynamo Table to store value like below [{"S" : "Test1"}, {"S":"Test8"},{"S" : "Test8"}]


Solution

  • For your first code block, you don't need the extra syntax when defining your ENTITIES attribute, since this is just regular PutItem API calls for the Item section. A normal JavaScript array will do. This is confirmed by the DynamoDB API PutItem Request Syntax

    And the modification to your first code block:

    {
      "CLIENT_ID": "fa1188",
      "CLIENT_NAME": "Country Village 1188",
      "SOURCE_IDENTIFIER": "abc-123-Country_Village 1188",
      "ENTITIES": ["Test1", "Test8", "Test8"],
      "CREATED_TIMESTAMP": "1597436891604"
    }
    

    For your state machine definition in your post's 2nd code block, you had the ENTITIES Attribute defined as a String Type with "S.$":"$.ENTITIES.L", and the .L at the end was unnecessary. Just change that Type definition from S to L for a List type instead.

    This is what it looks like with your original 2nd code block modified:

    {
      "Comment": "PutItem into DynamoDB",
      "StartAt": "1st",
      "States": {
        "1st": {
      "Type": "Task",
      "Resource": "arn:aws:states:::dynamodb:putItem",
      "Parameters": {
        "TableName": "CLIENTS",
        "Item": {
          "CLIENT_ID": {
            "S.$": "$.CLIENT_ID"
          },
          "CLIENT_NAME": {
            "S.$": "$.CLIENT_NAME"
          },
          "SOURCE_IDENTIFIER": {
            "S.$": "$.SOURCE_IDENTIFIER"
          },
        "CREATED_TIMESTAMP": {
            "S.$": "$.CREATED_TIMESTAMP"
        },
         "ENTITIES": {         
            "L.$":"$.ENTITIES"
         }
        }
        },
        "End":true,
        "ResultPath":"$.DynamoDB"
        }
      }
    }
    

    Tested and works as expected. The PutItem API handles the conversion from JS array types to DynamoDB list types under the hood:

    Successful result of DynamoDB PutItem with List of strings executed via Amazon States Language