skip to Main Content

Quite new to AWS / DynamoDB. I’m trying to make a UpdateItem method work on my API. I have a Resource with the path x/users/update/{wallet} with wallet being the key.

In here I set a UpdateItem method just like I have all my other Query / Scan / PutItem methods. this has the following mapping template:

{
    "TableName": "Users",
    "KeyConditionExpression": "wallet = :v1",
    "ExpressionAttributeValues": {
        ":v1": {
            "S": "$input.params('wallet')"
        }
        ":v2": {
            "S": $input.json('$.username')
        }
    }
    "UpdateExpression": "set username = :v2",
    "ReturnValues": "UPDATED_NEW"
}

This returns a 200 with "__type": "com.amazon.coral.service#SerializationException"

Pretty sure this is related to my Mapping template but can’t figure out what. Looked at the https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html and think I used the Sample Request in there as a template to test it like this

{
    "TableName": "Users",
    "Key": {
        "wallet": {
            "S": "$input.params('wallet')"
        },
    },
    "UpdateExpression": "SET username = :val1",
    "ExpressionAttributeValues": {
        ":val1": {
            "S": "$input.path('$.username')"
        },
    },
    "ReturnValues": "ALL_NEW"
}

payload is just as simple as

{"username":"test"}

but that gives the same result.

Any ideas on what i’m doing wrong here?

Cheers!

EDIT:
PutItem looks like this:

{ 
    "TableName": "Users",
    "Item": {
        "userId": {
            "S": "$context.requestId"
        },
        "date": {
            "S": "$input.path('$.date')"
        },
        "wallet": {
            "S": "$input.path('$.wallet')"
        }
    }
}

2

Answers


  1. DynamoDB UpdateItem takes a Key not a KeyConditionExpression

    This one below is correct:

    {
    "TableName": "Users",
    "Key": {
        "wallet": {
            "S": "$input.params('wallet')"
        },
    },
    "UpdateExpression": "SET username = :val1",
    "ExpressionAttributeValues": {
        ":val1": {"S": "$input.params('$.username')"},
    },
    "ReturnValues": "ALL_NEW"
    }
    

    You also state your payload is simply

    {"username":"test"}

    You must also specify wallet as this is the key

    Login or Signup to reply.
  2. It looks like you’re not accessing the record to update with the key of your table. Unlike SQL, you cannot access a record to update with any field in DynamoDB. You have to use your key depending on how you defined it (PK or PK + SK).

    Given that you have both PK and SK defined, you need them both in your key input. Together they form a composite primary key. The below input should work for you.

    {
        "TableName": "Users",
        "Key": {
            "wallet": {
                "S": "$input.params('wallet')"
            },
            "date": {
                "S": "$input.params('date')"
            },
        },
        "UpdateExpression": "SET username = :val1",
        "ExpressionAttributeValues": {
            ":val1": {
                "S": "$input.path('$.username')"
            },
        },
        "ReturnValues": "ALL_NEW"
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search