BETA

Lambda(Node.js)で同期処理っぽくDynamoDBからデータを取得したい

投稿日:2019-12-06
最終更新:2019-12-16

何がやりたかったのか?

  • Lambda(Node.js)からDynamoDBの結果を取得したかった
  • Unit Testを書きやすいように、責務ごとに複数のFunctionに分けた
  • DynamoDBの問い合わせ結果が非同期(コールバック:callback)で返ってくるので、returnできなかった

Node.jsは非同期で処理してしまう。
よく分かっていないと、DynamoDBからのコールバックを待たずにreturnされてしまい、
データが取得できないという事がある。

前提

実行環境

  • テストフレームワーク "jest": "^24.9.0"

プロジェクト構造

/src  
  |--/main  
    |--/controller  
      |-index.js  <-- Lambda実行元  
    |--/model  
      |--table.js  <-- データを操作するモデル(今回テストを書いたのはここ)  
    |--/infrastructure  
      |--dynamoTable.js  <-- DynamoDBに依存したインフラ層(実際にAWS-SDKを実行するのはここ)  
  |--/__tests__  
    |--teble.test.js  

どうやればいいか

teble.test.js

test('table を確認する', async () => {  
    let table = require('../main/model/teble');  

    expect(  
        await new table(  
            "columns1",  
            "columns2"  
        ).get()  
    ).toBe(想定する値);  

});  

table.js

const DynamoTable = require("../infrastructure/dynamoTable");  

class Table {  
    constructor(columns1,  
                columns2  
    ) {  
        this.columns1 = columns1;  
        this.columns2 = columns2;  
    }  

   get(){  
        const table = {  
            columns1: this.columns1,  
            columns2: this.columns2  
        };  

        return new DynamoTable().getData(table);  

    }  
}  

module.exports = Table;  

dynamoTable.js

const AWS = require("aws-sdk");  

class DynamoCustomerReserved {  

    async getData(table) {  
        const params = {  
            TableName: "Table",  
            Key: {  
                columns1: table.columns1,  
                columns2: table.columns2  
            }  
        };  

        AWS.config.update({  
            region: "ap-northeast-1"  
        });  
        const docClient = new AWS.DynamoDB.DocumentClient();  

        try {  
            const result = await docClient.get(params, function (err, data) {}).promise();  
            console.log(result);  
            return result["Item"];  
        } catch (err) {  
            console.error(err);  
        }  
    }  
}  

module.exports = Table;  

解説

DynamoDBのデータ取得は非同期で行われるので、それに合わせて書いてあげる必要があります。

まず、dynamoTable.js の

 async getData(table) {  

async でFunctionを定義します。

次にDynamoDBのデータを取得する際に

const result = await docClient.get(params, function (err, data) {}).promise();  

await から promise() でコールバックが戻ってくるまで待ち合わせをします。

これによって同期処理が行われるので、DynamoDBの取得結果をreturnできます。

チラ裏

awaitpromise()async でFunction定義をしていないと、そんなもの知らん!と実行時にエラーになります。

非同期のFunctionがあるよって教えてあげないと、Node.js君はなる早で処理を終わらそうとします。

参考

https://qiita.com/taqm/items/f22ee3c3f0fb3d433a85

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@takahashino1の技術ブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう