DynamoDB localの読み書きをNode.jsで行う

9 min read読了の目安(約8500字

こんにちわ、こんばんわ。さとかずです。
DyanmoDB localをNode.jsで読み書きするチュートリアルです。
基本的にAWSのドキュメントを参考にしています。

実行環境

Mac mini 2018(11.2.1)を利用しています。

Javaのインストール

Javaが必要なのでインストールしました。
別記事: macOSでjavaを使いたい

DynamoDB localのインストールと実行

  1. DynamoDBのダウンロード
    AWS -> Download Locally -> アジアパシフィック (東京) リージョン -> .tar.gzのリンクをダウンロードしました。

  2. ダウンロードしたファイルを展開

    $ mkdir -p ~/local/dynamodb
    $ mv ~/Downloads/dynamodb_local_latest.tar.gz ~/local/dynamodb
    $ cd ~/local/dynamodb
    $ tar zxvf ./dynamodb_local_latest.tar.gz
    
  3. 実行する

    $ java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb
    Initializing DynamoDB Local with the following configuration:
    Port:	8000
    InMemory:	false
    DbPath:	null
    SharedDb:	true
    shouldDelayTransientStatuses:	false
    CorsParams:	*
    

Node.jsの初期化と必要なライブラリのインストール

  1. Node.jsの初期化

    $ mkdir -p ~/Development/dynamo-first-app/
    $ cd ~/Development/dynamo-first-app/
    $ yarn add @aws-sdk/client-dynamodb 
    

    上記のパッケージで動作しなかったので、私は下記のようにしています

    yarn add aws-sdk
    

テーブルの作成

  1. テスト用のテーブルを作成する
    AWSのドキュメント通りにファイルを作成して実行する

    $ vim MoviesCreateTable.js
    ... 写経する
    $ node MoviesCreateTable.js
    Unable to create table. Error JSON:  {
      "message": "Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1",
      "code": "CredentialsError",
      ....
    

    credentialsがないと怒られた。

  2. MoviesCreateTable.jsのファイルを書き換える
    MACやLINUXの場合は、~/.aws/credentialsに下記の内容を追加する

    [dummy]
    aws_access_key_id = dummy
    aws_secret_access_key = dummy
    
  3. ~/.aws/credentialsのdummyを使用するようにMoviesCreateTable.jsを書き換える

    var AWS = require('aws-sdk');
    
    var myCredentials = new AWS.SharedIniFileCredentials({profile:'dummy'});
    var myConfig = new AWS.Config({
          credentials: myCredentials,
      region: 'us-west-2',
      endpoint: 'http://localhost:8000'
    });
    
    AWS.config = myConfig;
    
    // ここまでは他javascriptでも同様に変更する箇所となる。
    
    var dynamodb = new AWS.DynamoDB();
    
  4. テスト用のテーブルを作成する(再挑戦)
    AWSのドキュメント通りにファイルを作成して実行する

    $ node MoviesCreateTable.js
    Created table. Table description JSON:  {
      "TableDescription": {
        "AttributeDefinitions": [
          {
            "AttributeName": "year",
            "AttributeType": "N"
          },
          {
            "AttributeName": "title",
            "AttributeType": "S"
          }
        ],
        "TableName": "Movies",
        "KeySchema": [
          {
            "AttributeName": "year",
            "KeyType": "HASH"
          },
          {
            "AttributeName": "title",
            "KeyType": "RANGE"
          }
        ],
        "TableStatus": "ACTIVE",
        "CreationDateTime": "2021-03-16T11:11:36.534Z",
        "ProvisionedThroughput": {
          "LastIncreaseDateTime": "1970-01-01T00:00:00.000Z",
          "LastDecreaseDateTime": "1970-01-01T00:00:00.000Z",
          "NumberOfDecreasesToday": 0,
          "ReadCapacityUnits": 10,
          "WriteCapacityUnits": 10
        },
        "TableSizeBytes": 0,
        "ItemCount": 0,
        "TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/Movies"
      }
    }
    

データの登録

  1. サンプルデータをダウンロードして展開する

    $ wget https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/samples/moviedata.zip 
    $ unzip moviedata.zip
    

    中身を確認しておく。

    $ head -n 30 moviedata.json
    [
        {
            "year": 2013,
            "title": "Rush",
            "info": {
                "directors": ["Ron Howard"],
                "release_date": "2013-09-02T00:00:00Z",
                "rating": 8.3,
                "genres": [
                    "Action",
                    "Biography",
                    "Drama",
                    "Sport"
                ],
                "image_url": "http://ia.media-imdb.com/images/M/MV5BMTQyMDE0MTY0OV5BMl5BanBnXkFtZTcwMjI2OTI0OQ@@._V1_SX400_.jpg",
                "plot": "A re-creation of the merciless 1970s rivalry between Formula One rivals James Hunt and Niki Lauda.",
                "rank": 2,
                "running_time_secs": 7380,
                "actors": [
                    "Daniel Bruhl",
                    "Chris Hemsworth",
                    "Olivia Wilde"
                ]
            }
        },
        {
            "year": 2013,
            "title": "Prisoners",
            "info": {
                "directors": ["Denis Villeneuve"],
        
    
  2. データを追加する
    AWSドキュメントを参考にMoviesLoadData.jsを作成する

    $ vim MoviesLoadData.js
    ... 写経する
    
    $ node MoviesLoadData.js
    ...
    PutItem succeeded Henry's Crime
    PutItem succeeded Heart and Souls
    PutItem succeeded The Clinic
    PutItem succeeded Fast Girls
    PutItem succeeded Home Sweet Home
    

データの取得

登録したデータをクエリで絞り込み検索してみます。

  1. データをクエリで絞り込み検索する
    AWSドキュメントを参考にMoviesQuery02.js作成する

    $ vim MoviesQuery02.js
    ... 写経する
    
    $ node MoviesQuery02.js
    ...
    - 1985: Explorers ... Adventure,Family,Sci-Fi ... Ethan Hawke
    - 1985: Flesh+Blood ... Adventure,Drama ... Rutger Hauer
    - 1985: Friday the 13th: A New Beginning ... Horror,Mystery,Thriller ... Melanie Kinnaman
    - 1985: Fright Night ... Comedy,Horror,Thriller ... Chris Sarandon
    - 1985: Girls Just Want to Have Fun ... Comedy,Music,Romance ... Sarah Jessica Parker
    - 1985: Just One of the Guys ... Comedy,Romance ... Joyce Hyser
    

    yearは、予約語なので #yr を指定してExpressionAttributeNamesで置換します。
    titleは予約語ではないのでそのまま指定しても問題ありません。

テーブルの削除

お片付けも兼ねて使用したテーブルを削除します。

  1. 使用したテーブルを削除します。
    AWSドキュメントを参考にMoviesDeleteTable.jsを作成する

    $ vim MoviesDeleteTable.js
    ... 写経する
    
    $ node MoviesDeleteTable.js
    ...
    Deleted table. Table description JSON:  {
        "TableDescription": {
            "AttributeDefinitions": [
            {
                "AttributeName": "year",
                "AttributeType": "N"
            },
            {
                "AttributeName": "title",
                "AttributeType": "S"
            }
            ],
            "TableName": "Movies",
            "KeySchema": [
            {
                "AttributeName": "year",
                "KeyType": "HASH"
            },
            {
                "AttributeName": "title",
                "KeyType": "RANGE"
            }
            ],
            "TableStatus": "ACTIVE",
            "CreationDateTime": "2021-03-18T04:24:32.193Z",
            "ProvisionedThroughput": {
            "LastIncreaseDateTime": "1970-01-01T00:00:00.000Z",
            "LastDecreaseDateTime": "1970-01-01T00:00:00.000Z",
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 10,
            "WriteCapacityUnits": 10
            },
            "TableSizeBytes": 2095892,
            "ItemCount": 4611,
            "TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/Movies"
        }
    }
    

    これでテーブルが削除されました。
    もう一度クエリを実行するとテーブルがないためにエラーになることを確認します。

    $ node MoviesQuery02.js
    Querying for movies from 1992 - titles A-L, with genres and lead actor. 
    Unable to query. Error:  {
        "message": "Cannot do operations on a non-existent table",
        "code": "ResourceNotFoundException",
        "time": "2021-03-18T07:17:09.537Z",
        "requestId": "ceeac1fc-9e1e-480a-b96b-46bc973b15e5",
        "statusCode": 400,
        "retryable": false,
        "retryDelay": 48.57288337367669
    }
    

AWSの本番を利用しなくてもローカルである程度の実装テストができることがいいですね。
最初、Ver3の初期化してVer2で動作させようとしているので躓きました。

これで以上です。