こんにちは、CX事業本部 Delivery部の若槻です。
AWS SDK for JavaScript v3でDynamoDB JSONと通常のJSONの間でデータ構造の変換を行いたい場合は、@aws-sdk/util-dynamodb
のmarshall
およびunmarshall
を使うと便利です。
marshall
およびunmarshall
では、変換のされ方を変更するオプション(marshallOptions、unmarshallOptions)がいくつか用意されています。
const marshallOptions = {
// Whether to automatically convert empty strings, blobs, and sets to `null`.
convertEmptyValues: false, // false, by default.
// Whether to remove undefined values while marshalling.
removeUndefinedValues: false, // false, by default.
// Whether to convert typeof object to map attribute.
convertClassInstanceToMap: false, // false, by default.
};
const unmarshallOptions = {
// Whether to return numbers as a string instead of converting them to native JavaScript numbers.
wrapNumbers: false, // false, by default.
};
const translateConfig = { marshallOptions, unmarshallOptions };
const client = new DynamoDBClient({});
const ddbDocClient = DynamoDBDocument.from(client, translateConfig);
今回は、marshallOptionsおよびunmarshallOptionsを実際に試してみました。
試してみた
@aws-sdk/util-dynamodb
をインストールします。
npm i @aws-sdk/util-dynamodb
marshall
まずmarshallOptionsを試してみます。次のスクリプトで動作確認を行います。
import {
DynamoDBClient,
PutItemCommand,
GetItemCommand,
} from '@aws-sdk/client-dynamodb';
import { marshall, marshallOptions } from '@aws-sdk/util-dynamodb';
const client = new DynamoDBClient({
region: 'ap-northeast-1',
});
const main = async (hoge: any, fuga: any, marshallOption: marshallOptions) => {
const item = {
id: 'id',
hoge: hoge,
fuga: fuga,
};
await client.send(
new PutItemCommand({
TableName: 'sample',
Item: marshall(item, marshallOption),
})
);
const getItemOutput = await client.send(
new GetItemCommand({ TableName: 'sample', Key: marshall({ id: 'id' }) })
);
console.log(JSON.stringify(getItemOutput.Item, undefined, 2));
};
convertEmptyValues
marshallOptionsのconvertEmptyValues
は、空の値をnull
に変換するオプションです。
既定では無効となっています。
main('', [''], {});
{
"hoge": {
"S": ""
},
"id": {
"S": "id"
},
"fuga": {
"L": [
{
"S": ""
}
]
}
}
有効にすると、stringやsetの空の値がnull
に変換されました。
main('', [''], { convertEmptyValues: true });
{
"hoge": {
"NULL": true
},
"id": {
"S": "id"
},
"fuga": {
"L": [
{
"NULL": true
}
]
}
}
removeUndefinedValues
marshallOptionsのremoveUndefinedValues
は、値がundefined
であるプロパティを削除するオプションです。
既定では無効になっており、undefined
が指定された場合はmarshallの実行がエラーとなります。
main(undefined, undefined, {});
/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/@aws-sdk/util-dynamodb/dist-cjs/convertToAttr.js:7
throw new Error(`Pass options.removeUndefinedValues=true to remove undefined values from map/array/set.`);
^
Error: Pass options.removeUndefinedValues=true to remove undefined values from map/array/set.
at convertToAttr (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/@aws-sdk/util-dynamodb/dist-cjs/convertToAttr.js:7:15)
at /Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/@aws-sdk/util-dynamodb/dist-cjs/convertToAttr.js:118:54
at convertToMapAttrFromEnumerableProps (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/@aws-sdk/util-dynamodb/dist-cjs/convertToAttr.js:122:7)
at convertToAttr (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/@aws-sdk/util-dynamodb/dist-cjs/convertToAttr.js:23:16)
at marshall (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/@aws-sdk/util-dynamodb/dist-cjs/marshall.js:6:62)
at main (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/marshall.ts:22:21)
at Object.<anonymous> (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/marshall.ts:33:1)
at Module._compile (node:internal/modules/cjs/loader:1105:14)
at Module.m._compile (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/cdk_sample_app/node_modules/ts-node/src/index.ts:1618:23)
at Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
有効にすると、値がundefined
であるプロパティが削除されます。
main(undefined, undefined, { removeUndefinedValues: true });
{
"id": {
"S": "id"
}
}
エラーを防ぐために、値がundefined
になりうるオブジェクトをmarshallする場合は是非とも設定しておきたいオプションですね。
unmarshall
次にunmarshallOptionsを試してみます。次のスクリプトで動作確認を行います。
import { DynamoDBClient, GetItemCommand } from '@aws-sdk/client-dynamodb';
import {
marshall,
unmarshall,
unmarshallOptions,
} from '@aws-sdk/util-dynamodb';
const client = new DynamoDBClient({
region: 'ap-northeast-1',
});
const main = async (unmarshallOptions: unmarshallOptions) => {
const getItemOutput = await client.send(
new GetItemCommand({ TableName: 'sample', Key: marshall({ id: 'id' }) })
);
console.log(
JSON.stringify(
unmarshall(getItemOutput.Item!, unmarshallOptions),
undefined,
2
)
);
};
wrapNumbers
unmarshallOptionsのwrapNumbers
は、数値型の値をJavaScriptネイティブな値ではなく文字列型に変換します。
既定では無効になっています。
main({ wrapNumbers: false });
{
"hoge": 123,
"fuga": 11.11,
"id": "id"
}
有効にすると、次のような形式となります。
main({ wrapNumbers: true });
{
"hoge": {
"value": "123"
},
"fuga": {
"value": "11.11"
},
"id": "id"
}
おわりに
AWS SDK for JavaScript v3で@aws-sdk/util-dynamodbのmarshallOptions/unmarshallOptionsを試してみました。
参考
以上