Search code examples
node.jsamazon-dynamodb

MultipleValidationErrors with batchGetItem in DynamoDB using NodeJS


I'm trying to make a filter to obtain more than one record in a DynamoDB table. I'm using the function batchGetItem with NodeJS inside an AWS Lambda as the API. Below is what my params look like.

Note: I tried multiple ways to create those params. I used single/double quotes/no quotes; I also passed each item with its type ( {PK: {S: 'Request#10001'}} ), and none of those worked.

Context: my table name is RequestTable, and it has a column named "PK" (defined as String) and "SK" (defined as String). If I apply the exact same filter in the DynamoDB UI (ex: PK == "Request#10001" AND SK == "Client"), it works.

const AWS = require('aws-sdk');
const client = new AWS.DynamoDB();

const params = {
    RequestItems: {
        "RequestTable": {
            Keys: [
                {PK: 'Request#10001', 'SK': 'Client'},
                {PK: 'Request#10002', 'SK': 'Client'}
            ]
        }
      }
    }

client.batchGetItem(params, function(err, data) {
    if (err) {
      console.log("Error", err);
    } else {
      data.Responses.RequestTable.forEach(function(element, index, array) {
        console.log(element);
      });
    }
  });

However, I'm not able to make this work, because I keep having errors that look like this:

Error MultipleValidationErrors: There were 6 validation errors:
* MissingRequiredParameter: Missing required key 'RequestItems' in params
* UnexpectedParameter: Unexpected key 'TableName' found in params
* UnexpectedParameter: Unexpected key 'IndexName' found in params
* UnexpectedParameter: Unexpected key 'KeyConditionExpression' found in params
* UnexpectedParameter: Unexpected key 'ExpressionAttributeNames' found in params
* UnexpectedParameter: Unexpected key 'ExpressionAttributeValues' found in params

Any ideas on how could I solve that?

I tried playing around with the options available and trying to make it look like the following AWS resources: Read in Batch AWS DynamoDB Example, but no success.


Solution

  • I have a couple of issues with your code:

    1. You use high level syntax with the low-level client. Take some time to familiarise yourself with the different available clients
    2. You use SDK V2, while SDK V3 is the current default and allows your application to be much leaner, as its modular:
    const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
    const { DynamoDBDocumentClient, BatchWriteCommand } = require("@aws-sdk/lib-dynamodb");
    
    const client = new DynamoDBClient({});
    const ddbDocClient = DynamoDBDocumentClient.from(client);
    
    async function batchGetItems() {
     
      try {
        return await ddbDocClient.send(
            new BatchGetCommand({
              RequestItems: {
                RequestTable: {
                  Keys: [
                    {PK: 'Request#10001', 'SK': 'Client'},
                    {PK: 'Request#10002', 'SK': 'Client'}
                  ],
                },
              },
            })
        );
      } catch (err) {
        console.error(err);
      }
    }
    
    batchGetItems()
        .then((data) =>
            console.log("BatchGetCommand succeeded:", JSON.stringify(data, null, 2)))
        .catch((error) => console.error(JSON.stringify(error, null, 2)));
    
    1. Regardless if you use SDK V2/V3 the parameter syntax will be the same, so you can utilize the same syntax as I provided for params for the V2 DocumentClient.