AWS SDK for Node.js での DynamoDB と DynamoDB.DocumentClient の違い

はじめに

おばんです、iOSエンジニアからサーバーサイドエンジニアに転向しつつある田中です。iOS/Objective-C/Swiftしかやってこなかったので新鮮デス。

ここ一週間はNode.js, AWSの学びはじめとして、先輩の書いた既存コードを読みつつ機能追加したりしているのですが、今日はそんな中で見つけたちょっとした書き方とその意味の違いについてまとめます。

DynamoDB();DynamoDB.DocumentClient();という二つの書き方

結論から言うと、 この二つの違いはDynamoDBのレコードを操作するときに使う AttributeValue を省略できるところになります。 DynamoDB.DocumentClient(); の書き方の方が AttributeValue を省略できます。

DynamoDBはAWS CLIから叩く生のAPIと近いインターフェースになっていて(例えばこの記事でも紹介しているputItemという関数はAWS CLIではこうなっています)、DocumentClientはそのラッパーとして AttributeValue を省略できる形になっています。

この二つの書き方で実装されている関数をそれぞれの公式リファレンスを見比べてみると、 DynamoDB(); の方にはテーブル操作などのインターフェースがあり、 DynamoDB.DocumentClient(); の方にはテーブル操作などのインターフェースは無く、レコード操作のインターフェースのみが存在するようです。

詳しくは以下の二つのリファレンスより。

具体的な差異をコードで紹介

こちらに DynamoDB();DynamoDB.DocumentClient(); を用いたサンプルコードがあります。

const aws = require('aws-sdk');

// DynamoDB();
const ddb = new aws.DynamoDB();
const ddbParams = {
  TableName: "xxx-xxx-xxx-xxx-User",
  Item: {
    "name": { "S" : "ktanaka117" },
    "age": { "N" : "23" }
  }
};
ddb.putItem(ddbParams);

// DynamoDB.DocumentClient();
const ddbdc = new aws.DynamoDB.DocumentClient();
const ddbdcParams = {
  TableName: "xxx-xxx-xxx-xxx-User",
  Item: {
    "name": "ktanaka117",
    "age": 23
  }
};
ddbdc.put(ddbdcParams);

DynamoDB(); では更新するレコードに AttributeValue というDynamoDB上での型をparameterに指定する必要があります。

DynamoDB.DocumentClient(); ではなぜ AttributeValue の指定が必要ないかといえば、SDK内部でネイティブJavaScriptの型にマーシャリング/アンマーシャリングしてくれているからだそうです。(DynamoDB.DocumentClientの "Marshalling Input and Unmarshalling Response Data" より)

おまけ: DocumentClientを用いた際のParameterの型指定について

DynamoDB(); を用いる場合、parameterには型情報が必要になるというのは先述した通りです。以下のコードのようになります。parameterのageをDynamoDBにString型で保存するか、Number型で保存するかという差があります。どちらも値に対して "" または '' で指定します。

// ageがString型として保存される
const stringAgeParams = {
  TableName: "xxx-xxx-xxx-xxx-User",
  Item: {
    "name": { "S" : "ktanaka117" },
    "age": { "S" : "23" }
  }
};

// ageがNumber型として保存される
const numberAgeParams = {
  TableName: "xxx-xxx-xxx-xxx-User",
  Item: {
    "name": { "S" : "ktanaka117" },
    "age": { "N" : "23" }
  }
};

一方で DynamoDB.DocumentClient(); を用いた場合は型情報は付属させないため、値をどのように指定するかによってDynamoDBに保存される型情報が変わるので注意が必要です。( "" または '' でくくると、String型になる)

// ageがString型として保存される
const stringAgeParams = {
  TableName: "xxx-xxx-xxx-xxx-User",
  Item: {
    "name": "ktanaka117",
    "age": "23"
  }
};

// ageがNumber型として保存される
const numberAgeParams = {
  TableName: "xxx-xxx-xxx-xxx-User",
  Item: {
    "name": "ktanaka117",
    "age": 23
  }
};

さいごに

DynamoDB();DynamoDB.DocumentClient(); という二つの書き方の違いについて、実際のサンプルコードも交えながら紹介しました。

AWS SDKにはこういうラッパーが各所に存在するのか、まだ他のサービスを追えているわけではないのでわかりませんが、おまけでも解説した点にも注意しながら適材適所に応じて使い分けていきたいところです。

参考・関連