bokunonikki.net
JP / EN

AWS SDKでDynamoDBのJSONのデータ型を取り除く

Sun Aug 21, 2022
Sun Aug 21, 2022

lambdaからDynamoDBから取得した際にJSONにデータ型がついていました。こんな感じで。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
"Items": [
  {
    "name": {
      "S": "Taro"
    },
    "number": {
      "N": "1"
    }
  }
]

この状態でフロントに返すと何かと面倒なので普通のJSONで返したい。まぁ、こういう形ですね。

1
2
3
4
5
6
"Items": [
  {
    "name": "Taro",
    "number": 1
  }
]

環境は以下になります。

  • AWS-SDK(Javascript v3)
  • lambda (TypeScript)

まずは素直に@aws-sdk/client-dynamodbを使ってScanしてきます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import {
  DynamoDBClient,
  ScanCommand,
  ScanCommandInput,
  ScanCommandOutput
} from "@aws-sdk/client-dynamodb";

const client = new DynamoDBClient({});
const params: ScanCommandInput = {
  TableName: "Table"
};
try {
  const command = new ScanCommand(params);
  const response = client.send(command);
  return response;
} catch (error) {
  return error;
}

これだと普通にデータ型のレスポンスが返ってきます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
  "Items": [
    {
      "name": {
        "S": "Taro"
      },
      "number": {
        "N": "1"
      }
    }
  ]

これを普通のJSONにする方法は2つあります。

1つ目は@aws-sdk/util-dynamodbを使うやり方です。

ドキュメントにもある通り返ってきた値にunmarshallでコンバートします。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const { DynamoDB } = require("@aws-sdk/client-dynamodb");
const { marshall, unmarshall } = require("@aws-sdk/util-dynamodb");

const client = new DynamoDB(clientParams);
const params = {
  TableName: "Table",
  Key: marshall({
    HashKey: "hashKey",
  }),
};

const { Item } = await client.getItem(params);
unmarshall(Item);

2つ目は@aws-sdk/lib-dynamodbを使うやり方です。こっちの方がスマートですし、何より自動でやってくれるので便利です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import {DynamoDBClient} from "@aws-sdk/client-dynamodb";
import {
  DynamoDBDocument,
  ScanCommand,
  ScanCommandInput,
  ScanCommandOutput
} from "@aws-sdk/lib-dynamodb";

const marshallOptions = {
  convertEmptyValues: false, // false, by default.
  removeUndefinedValues: false, // false, by default.
  convertClassInstanceToMap: false // false, by default.
};
const unmarshallOptions = {
  wrapNumbers: false // false, by default.
};

const translateConfig = {marshallOptions, unmarshallOptions};
const client = new DynamoDBClient({});
const ddbDocClient = DynamoDBDocument.from(client, translateConfig);
 
const params: ScanCommandInput = {
  TableName: "Table"
};
try {
  const command = new ScanCommand(params);
  const response = ddbDocClient.send(command);
  return response;
} catch (error) {
  return error;
}

これで普通のJSONが返ってきました。

See Also