Node.js からDynamoDBを操作するサンプル


[Node.js で AWSを操作する環境を作る（Mac)]
(http://qiita.com/inouet/items/2798cbbc677d7141904a) の続きです。
Node.jsからDynamoDBのオペレーションを試してみます。

# 00. 準備

* [Node.js で AWSを操作する環境を作る（Mac)]
(http://qiita.com/inouet/items/2798cbbc677d7141904a) が終わっている前提です。
* 各ファイルでは下記のような共通の処理が入っていますが、記述を省略しています。

```js
var AWS = require('aws-sdk');
var php = require('phpjs');

var dynamodb = new AWS.DynamoDB({region: 'ap-northeast-1'});

```

※ phpjs は完全に趣味なのでスルーしてだいじょうぶです。php.var_dump()、php.print_r() は console.log() の代用としています。

# 01. list-tables (テーブル一覧)

## プログラム:

```js

var params = {
    Limit: 100
};

dynamodb.listTables(params, function(err, data) {
    if (err) {
        console.log(err, err.stack); 
    } else {
        console.log(data);
        // php.print_r(data);
    }
});
```

# 02. describe-table （テーブル詳細表示）

## プログラム:

```js
var params = {TableName:'json_test'};
dynamodb.describeTable(params, function(err, data) {
    if (err) {
        console.log(err, err.stack);
    } else {
        console.log(data);
        // php.var_dump(data);
    }
});
```

## 出力: 

```

$ node describe-table.js

{ Table:
   { AttributeDefinitions: [ [Object] ],
     CreationDateTime: Sun Nov 09 2014 09:01:08 GMT+0900 (JST),
     ItemCount: 1,
     KeySchema: [ [Object] ],
     ProvisionedThroughput:
      { NumberOfDecreasesToday: 0,
        ReadCapacityUnits: 1,
        WriteCapacityUnits: 1 },
     TableName: 'json_test',
     TableSizeBytes: 74,
     TableStatus: 'ACTIVE' } }
```

console.log のところをコメントアウトして、php.var_dump(data); の方で実行すると、[Object] の中身も見られてすごい便利。

なんか邪道な気がするけど。正式なやり方あったら教えてください。

# 03. put-table （データ登録）

## プログラム:

```js
var params = {
    TableName: 'json_test',
    Item: {
        'id':       {"S": "1003"},
        'name':     {"S": "orange"},
        'price':    {"N": "210"}
    }
};

// "N": 210 のように数値で入れたらエラーになった。

dynamodb.putItem(params, function (err, data) {
    if (err) {
        console.log(err, err.stack);
    } else {
        console.log(data);
    }
});
```

# 04. scan-table （全件出力）

## プログラム:

```js
var params = {
    TableName: 'json_test',
    Select: "ALL_ATTRIBUTES"
};

dynamodb.scan(params, function (err, res) {
    php.var_dump(res);
});

```

## 出力:
```
array(3) {
    [Count] =>
    int(1)
    [Items] =>
    array(1) {
            [0] =>
            array(3) {
                    [name] =>
                    array(1) {
                            [S] =>
                            string(6) "orange"
                    }
                    [id] =>
                    array(1) {
                            [S] =>
                            string(4) "1003"
                    }
                    [price] =>
                    array(1) {
                            [N] =>
                            string(3) "210"
                    }
            }
    }
    [ScannedCount] =>
    int(1)
}
```

# 05. get-item （１件取得）

## プログラム:

Keyにプライマリキーを渡す。

```js
var params = {
    TableName: 'json_test',
    Key: {
        "id": {"S": "1003"}
    }
};

dynamodb.getItem(params, function (err, res) {
    php.var_dump(res);
});

```

## 出力:

```
array(1) {
    [Item] =>
    array(3) {
            [name] =>
            array(1) {
                    [S] =>
                    string(6) "banana"
            }
            [id] =>
            array(1) {
                    [S] =>
                    string(4) "1002"
            }
            [price] =>
            array(1) {
                    [N] =>
                    string(2) "80"
            }
    }
}
```

# 06. update-item

## プログラム:

```js

var params = {
    TableName: 'json_test',
    Key: {
        "id": {"S": "1003"} // Hashキー
    },
    AttributeUpdates: {
        "price": {
            'Action': 'PUT',
            'Value': {"N": "30"}
        }
    }
};

dynamodb.updateItem(params, function (err, res) {
    php.var_dump(err);
    php.var_dump(res);
});

```

上記サンプルでは、AttributeUpdates 使ってますが、Developpers.IOで下記のような情報を見かけました。おうふ

> updateItemのパラメータにAttributeUpdatesを使うのは非推奨
http://dev.classmethod.jp/cloud/aws/dynamodb_updateexpression/


# 07. query

## プログラム:

```js
var params = {
    TableName: 'json_test',
    KeyConditions: {
        'id': {
            'ComparisonOperator': 'EQ',
            'AttributeValueList': [{S: '1002'}]
        }
    }
}

dynamodb.query(params, function (err, data) {
        if (err) {
            console.log(err);
        } else {
            php.var_dump(data);
        }
    }
);
```

# 08. delete-item

## プログラム: 

```js
var params = {
    TableName: 'json_test',
    Key: {
        "id": {"S": "1009"}
    }
};

dynamodb.deleteItem(params, function (err, res) {
    php.var_dump(err);
    php.var_dump(res);
});
```

# 09. batch-get-item

ドキュメント見てもよく分からず。 stackoverflowでも混乱ぎみ。

## プログラム:

http://stackoverflow.com/questions/15043043/how-to-use-batchgetitem-for-the-nodejs-aws-sdk-for-dynamodb

```js
var params = {
    RequestItems : {
        "json_test": {
            Keys: [
                {
                    "id": {S: "1002"}
                },
                {
                    "id": {S: "1003"}
                }
            ]
        }
    }
};

dynamodb.batchGetItem(params, function (err, res) {
    php.var_dump(res);
});
```

結局はこういうことらしい。

```
"RequestItems": {
    "<TableName>": {
        "Keys": [
            {"<HashKeyName>": {"<type>":"<hash key value>"}},
            {"<HashKeyName>": {"<type>":"<hash key value>"}},
            {"<HashKeyName>": {"<type>":"<hash key value>"}}
        ]
    }
}
```


# 10. batch-write-item

## プログラム:

```js
var params = {
    RequestItems: {
        "json_test": [
            {
                PutRequest: {
                    Item: {
                        'id': {"S": "2001"},
                        'name': {"S": "batch-put-item-1!"},
                        'price': {"N": "9990"}
                    }
                }
            },
            {
                PutRequest: {
                    Item: {
                        'id': {"S": "2002"},
                        'name': {"S": "batch-put-item-2!"},
                        'price': {"N": "9991"}
                    }
                }
            },

        ]
    }
}

dynamodb.batchWriteItem(params, function (err, res) {
    php.var_dump(res);
});
```


# 雑感

やっぱり、素のSDKをそのまま使うのはつらいなぁ。良いラッパー的なのが欲しい。
あんまりちゃんと調べてないですが、これとか良いかもしれない。 

* [[nodejs] DynamoDB ODMのvogelsをJSON形式に対応させた | 踊る犬.net](http://odoruinu.net/blog/2014/10/27/nodejs-dynamodb-odm-vogels-json/)
* [noradaiko/vogels](https://github.com/noradaiko/vogels)



# 参考

* [AWSJavaScriptSDK/latest/AWS/DynamoDB](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html#putItem-property)