DynamoDB GetItem in Node.js (AWS SDK v3)
AWS SDK v3 gives you two ways to read one item: GetItemCommand on a DynamoDBClient, which speaks the wire format ({S: '...'}), or GetCommand on a DynamoDBDocumentClient, which takes and returns plain JavaScript.
The example uses the low-level client. Those wrappers are what the attribute-value encoding actually looks like on the wire, and what error messages quote back at you. Either way the request needs the full primary key.
Code
import {DynamoDBClient, GetItemCommand} from '@aws-sdk/client-dynamodb';
const client = new DynamoDBClient({region: 'us-east-1'});
const command = new GetItemCommand({
TableName: 'Music',
Key: {
Artist: {S: 'Arturo Sandoval'},
SongTitle: {S: 'Cubano Chant'}
},
ProjectionExpression: '#proj0, #proj1, #proj2, #proj3',
ExpressionAttributeNames: {
'#proj0': 'Artist',
'#proj1': 'SongTitle',
'#proj2': 'AlbumTitle',
'#proj3': 'Year'
}
});
const response = await client.send(command);
if (!response.Item) {
console.log('Item not found');
} else {
console.log(response.Item);
}Explanation
send(command), notclient.getItem()—DynamoDBClientexposes onlysend. The aggregatedDynamoDBclass from the same package does carry agetItemmethod if you want SDK-v2-style calls, at the price of pulling every command into your bundle.- A miss is
undefined, not an error —response.Itemis simply absent, and the call still resolves.response.$metadataalways arrives, so truthiness on the response itself tells you nothing. unmarshallpicks the number type by magnitude — an{N: …}inside the safe-integer range comes back as anumber, anything outside it as aBigInt, and a large non-integer throwscan't be converted to BigInt. Pass{wrapNumbers: true}tounmarshallfrom@aws-sdk/util-dynamodband every number arrives as aNumberValueinstead, so you decide the conversion.- The
#projaliases are load-bearing —Yearis on AWS's reserved-word list, so aProjectionExpressionnaming it directly is rejected. Aliasing every name, as above, is the safe default. It trims the response, not the read cost (why). ConsumedCapacityis opt-in — addReturnConsumedCapacity: 'TOTAL'and the response reports what this read actually cost: 0.5 capacity units for an eventually consistent read of an item under 4 KB, 1.0 once you addConsistentRead: true(the trade-off).- Hoist the client — construct
DynamoDBClientonce at module scope. Building one per request, or inside a Lambda handler, throws away the connection pool and the resolved credentials on every call.
Do it visually
DynoTable shows items as ordinary rows rather than attribute-value maps, and exports the query behind the grid as a runnable SDK v3 program. Download DynoTable.
Related guides
- Query vs. Scan — when a single
GetItembeats aQuery. - How DynamoDB partition keys work — why
GetItemneeds the full key. - DynamoDB ResourceNotFoundException — the usual first error here: wrong table name or region.
- "The provided key element does not match the schema" — the key you pass doesn't match the table's key schema.
References
- GetItem — Amazon DynamoDB API Reference
- GetItemCommand — AWS SDK for JavaScript v3 Reference
- Read consistency — Amazon DynamoDB Developer Guide
- Capacity unit consumption — Amazon DynamoDB Developer Guide
- @aws-sdk/lib-dynamodb — large numbers and
NumberValue
Last verified 2026-07-28 against the official AWS documentation linked above.