Tofig Hasanov
Tofig Hasanov

Reputation: 3709

Generating JSON object with dynamic keys in AWS Step Functions

Background:
I am trying to add DynamoDB:GetItem step to my state machine in AWS Step Functions. GetItem API takes input in the following format:

{
  "TableName": "MyDynamoDBTable",
  "Key": {
    "Column": {
      "S": "MyEntry"
    }
  }
}

where "Column" is the primary key name, and "MyEntry" is the primary key value. The issue is that I want to be able to specify both primary key name and value dynamically, using JSON path reference.

Unfortunately, AWS won't allow me to pass value reference for primary key name ("Column"). So I can't do something like

{
  "TableName": "MyDynamoDBTable",
  "Key.$": {
    "$.ColumnName": {
      "S": "MyEntry"
    }
  }
}

Problem:

The only workaround I could think of (albeight a bit ugly) is to use combination of States.StringToJson and States.Format intrinsic functions to first generate stringified version of the input to Key.$ field, and then convert to JSON from string. Something like:

{
  "TableName.$": "$.TableName",
  "Key.$": "States.StringToJson(States.Format('\{\"{}\":\{\"S.$\":\"{}\"\}\}', $.PrimaryKeyName, $.PrimaryKeyValue))"
  }

It should work in theory, but it seems that AWS Step Functions is not happy about escaping double quotes? It's not able to parse the definition above.

So my question is:
Is there a way to make this work? (either by escaping double quotes somehow, or through a totally different approach)

Upvotes: 8

Views: 2215

Answers (1)

Tofig Hasanov
Tofig Hasanov

Reputation: 3709

After lots of experimentation, I finally found a way to make dynamic keys work. I am using Pass step with the following parameters defined:

{
  "Key.$": "States.StringToJson(States.Format('\\{\"{}\":\\{\"S\":\"{}\"\\}\\}', $.HashKeyName, $.HashKeyValue))"
}

The secret, apparently, was in using double \\ when escaping { and } symbols. Escaping " wasn't a problem after all, even though it's not documented in AWS docs.

The result of this transformation is following:

{
  "Key": {
    "MyHashKeyName": {
      "S": "MyHashKeyValue"
    }
  }
}

Upvotes: 8

Related Questions