DynamoDB Data Type Marshaller and Update Expression Builder
dynamodb-data-types is a JavaScript utility library designed to simplify the interaction with Amazon DynamoDB's native data type representations. It provides functions to convert standard JavaScript objects into DynamoDB's attribute value format (marshalling) and vice-versa (unmarshalling), handling complex nested structures and various primitive types. The library's current stable version is 4.0.1. Its release cadence is moderate, with major versions introducing significant features like the `UpdateExpression` builder in v4.0.0. A key differentiator is its focus on accurately handling DynamoDB's specific type mappings (e.g., numbers as strings `{N: '1'}`, sets, lists, maps, booleans, and nulls), alongside its ability to construct complex `UpdateExpression` payloads, including automatic handling of DynamoDB reserved keywords and proper `ExpressionAttributeValues` and `ExpressionAttributeNames` generation. This functionality reduces boilerplate code and common errors when performing update operations.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'wrap')
cause Attempting to call `wrap` directly from the package import instead of through `AttributeValue`.fixUse `import { AttributeValue } from 'dynamodb-data-types';` then call `AttributeValue.wrap(data)`. -
The provided expression refers to an attribute that does not exist in the item.
cause Attempting to use `REMOVE` or `DELETE` on an attribute that is not present, or trying to remove specific elements from a non-set type.fixEnsure the attribute exists before attempting `REMOVE` and verify that `DELETE` is only used for set types with appropriate values. Consider using `SET` with `null` if the intent is to clear an attribute's value rather than remove the attribute entirely. -
ValidationException: An ExpressionAttribute value is not defined for the SET update expression.
cause Incorrectly constructing the `SET` clause in an `UpdateExpression`, often by providing an empty object or invalid values.fixEnsure that the object passed to `.set()` contains valid key-value pairs representing the attributes to be set, and that values are of appropriate JavaScript types that can be marshalled by the library.
Warnings
- breaking Version 4.0.0 introduced significant changes to the API, most notably the addition of the `updateExpr()` builder. While `AttributeValue.wrap` and `unwrap` largely remained the same, direct access to some internal utilities might have changed.
- gotcha When using `updateExpr()`, ensure you call `.expr()` at the end of your chain to generate the final `UpdateExpression` object. Forgetting this will result in returning the builder instance instead of the desired expression.
- gotcha DynamoDB's `UpdateExpression` clauses (SET, ADD, REMOVE, DELETE) have specific behaviors. For instance, `ADD` can increment numbers or add items to sets, but cannot append to lists. `DELETE` is for removing elements from sets, not for deleting entire attributes (which `REMOVE` does).
Install
-
npm install dynamodb-data-types -
yarn add dynamodb-data-types -
pnpm add dynamodb-data-types
Imports
- AttributeValue
const AttributeValue = require('dynamodb-data-types').AttributeValue;import { AttributeValue } from 'dynamodb-data-types'; - updateExpr
const updateExpr = require('dynamodb-data-types').updateExpr;import { updateExpr } from 'dynamodb-data-types'; - wrap
import { wrap } from 'dynamodb-data-types';import { AttributeValue } from 'dynamodb-data-types'; const wrappedData = AttributeValue.wrap(data);
Quickstart
import { AttributeValue, updateExpr } from 'dynamodb-data-types';
async function demonstrateDynamoDBUtils() {
const originalData = {
id: 'user#123',
username: 'jsmith',
email: 'jsmith@example.com',
age: 30,
preferences: {
theme: 'dark',
notifications: true
},
tags: ['active', 'premium'],
lastLogin: null
};
// Marshalling JavaScript object to DynamoDB format
const marshalledData = AttributeValue.wrap(originalData);
console.log('Marshalled Data:', JSON.stringify(marshalledData, null, 2));
// Expected: { id: {S: 'user#123'}, username: {S: 'jsmith'}, ... }
// Unmarshalling DynamoDB format back to JavaScript object
const unmarshalledData = AttributeValue.unwrap(marshalledData);
console.log('Unmarshalled Data:', JSON.stringify(unmarshalledData, null, 2));
// Expected: { id: 'user#123', username: 'jsmith', ... }
// Building an UpdateExpression for a DynamoDB UpdateItem API call
const updatePayload = updateExpr()
.set({
email: 'john.smith@example.com',
'preferences.theme': 'light' // Nested attributes supported
})
.add({ age: 1 }) // Increment age by 1
.remove('lastLogin')
.delete({ tags: ['active'] }) // Remove 'active' from the tags set/list
.expr(); // Generate the final expression object
console.log('Update Expression Payload:', JSON.stringify(updatePayload, null, 2));
/* Expected:
{
UpdateExpression: "SET email = :a, #A.#B = :b ADD age :c REMOVE lastLogin DELETE tags :d",
ExpressionAttributeValues: { ":a": {"S":"john.smith@example.com"}, ":b": {"S":"light"}, ":c": {"N":"1"}, ":d": {"SS":["active"]} },
ExpressionAttributeNames: { "#A":"preferences", "#B":"theme" }
}
*/
}
demonstrateDynamoDBUtils();