DEV Community

Nikola Bintev
Nikola Bintev

Posted on

5

DynamoDB QueryCommand in AWS SDK JS v3

The AWS SDK for JavaScript v3 introduces the concept of modular architecture which encapsulates each service into a separate package. It means that you no longer need to import the whole AWS SDK package, but only the services that you need to use. This significantly reduces the size of your application.

It also comes with a new middleware stack to control the lifecycle of an operation call and TypeScript support. You can read more about it here.

Despite the nice features, migrating from v2 to v3 comes with some complexity that we'd like to highlight.

Marshalled/Unmarshalled data

The data that is sent as input to a given DynamoDb command must be marshalled. Marshalling is simply adding the type of the value to the JSON object

JSON object:

ExpressionAttributeValues: {
  ':username': 'somename',
  ':email': 'some@name.com'
},
Enter fullscreen mode Exit fullscreen mode

Marshalled JSON object:

ExpressionAttributeValues: {
  ':username': {S: 'somename'},
  ':email': {S: 'some@name.com'}
},
Enter fullscreen mode Exit fullscreen mode

Respectively, the command's response must be unmarshalled.

Examples

The examples are based on the assumption that we have a users table that has a partition key called username and sort key - email.

Note: The AWS credentials are not covered in the examples below.

Example 1: Send a query command with manually marshalled data.

  1. Import DynamoDBClient and QueryCommand modules from @aws-sdk/client-dynamodb
  2. The QueryCommand expects ExpressionAttributeValues to be a marshalled JSON object, so we explicitly set the type of the values
  3. The commands are executed by using the send method of the DynamoDBClient which accepts the command as the first argument.
import { DynamoDBClient, QueryCommand } from "@aws-sdk/client-dynamodb";

export const dynamoDbClient = new DynamoDBClient({region: 'eu-central-1'});

// The ExpressionAttributeValues must be marshalled,
// so the type of the values are explicitly set.
const params = {
  TableName: 'users',
  KeyConditionExpression: 'username = :username and email = :email',
  ExpressionAttributeValues: {
    ':username': {S: 'somename'},
    ':email': {S: 'some@name.com'}
  },
};

try {
  const response = await dynamoDbClient.send(new QueryCommand(params));
}
catch (e) {
  console.error(e.message);
}
Enter fullscreen mode Exit fullscreen mode

Example 2: Send a query command by using a utility module to marshall/unmarshall the data.

Instead of explicitly specifying the type of the values for the ExpressionAttributeValues key, we can use the marshall/unmarshall modules that come from the @aws-sdk/util-dynamodb package.

import { DynamoDBClient, QueryCommand } from "@aws-sdk/client-dynamodb";
import { marshall, unmarshall } from '@aws-sdk/util-dynamodb';

export const dynamoDbClient = new DynamoDBClient({region: 'eu-central-1'});

// The ExpressionAttributeValues must be marshalled,
// so the type of the values are explicitly set.
const params = {
  TableName: 'users',
  KeyConditionExpression: 'username = :username and email = :email',
  ExpressionAttributeValues: marshall({
    ':username': 'somename',
    ':email': 'some@name.com'
  }),  
};

try {
  const response = await dynamoDbClient.send(new QueryCommand(params));
}
catch (e) {
  console.error(e.message);
}
Enter fullscreen mode Exit fullscreen mode

Example 3: Send a query command by using @aws-sdk/lib-dynamodb

The @aws-sdk/lib-dynamodb automatically handles the necessary marshalling and unmarshalling of the data.

The only difference is that the QueryCommand is imported from the @aws-sdk/lib-dynamodb package instead of @aws-sdk/client-dynamodb and no manual marshalling is needed.

import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import { QueryCommand } from '@aws-sdk/lib-dynamodb';

export const dynamoDbClient = new DynamoDBClient({region: 'eu-central-1'});

// The ExpressionAttributeValues will be automatically
// marshalled by the @aws-sdk/lib-dynamodb.
const params = {
  TableName: 'users',
  KeyConditionExpression: 'username = :username and email = :email',
  ExpressionAttributeValues: {
    ':username': 'somename',
    ':email': 'some@name.com'
  },
};

try {
  const response = await dynamoDbClient.send(new QueryCommand(params));
}
catch (e) {
  console.error(e.message);
}
Enter fullscreen mode Exit fullscreen mode

Bottom line

The AWS SDK for JavaScript v3 introduces the ES6 modules which can reduce the size of our applications. It also comes with some nice features like a new middleware stack and TypeScript support, however, migrating from v2 to v4 might be a bit tricky and requires code changes.

Neon image

Resources for building AI applications with Neon Postgres πŸ€–

Core concepts, starter applications, framework integrations, and deployment guides. Use these resources to build applications like RAG chatbots, semantic search engines, or custom AI tools.

Explore AI Tools β†’

Top comments (3)

Collapse
 
nikolabintev profile image
Nikola Bintev β€’

Hi @debnathweb,

The article itself does not cover the credentials management. You can do it with an access key and secret access key, or you can assume a role with the needed permissions.

Collapse
 
bonespiked profile image
bonespiked β€’

ok - 2 years old, but always use a role whenever possible. Only use key/secrets when accessing AWS resources from outside of AWS and cannot assume a role.

Just be sure to put the appropriate permissions to access the DynamoDB table on the role.. :)

Collapse
 
debnathweb profile image
Debnath β€’

how to with cognito identity pool creadential
DynamoDBClient({region: 'eu-central-1'});

Jetbrains image

Build Secure, Ship Fast

Discover best practices to secure CI/CD without slowing down your pipeline.

Read more

πŸ‘‹ Kindness is contagious

Explore a trove of insights in this engaging article, celebrated within our welcoming DEV Community. Developers from every background are invited to join and enhance our shared wisdom.

A genuine "thank you" can truly uplift someone’s day. Feel free to express your gratitude in the comments below!

On DEV, our collective exchange of knowledge lightens the road ahead and strengthens our community bonds. Found something valuable here? A small thank you to the author can make a big difference.

Okay