AWS+NodeJSでサーバレスな環境構築⑤

# はじめに
[前回](https://qiita.com/isacRU/items/b4ab67d12f2d2377aea8)ではAPI Gateway(REST API)+Lambda(NodeJS)+DynamoDBの組み合わせてCRUDを作りました。今回はS3+Lambda+DynamoDBを組み合わせていきます。S3をトリガー（S3バケットにJsonファイルがアップロードされた段階)にし、Lambda(NodeJS)で取得したJson形式のデータをDynamoDBテーブルに保存します。
表現等がわかりにくければ、容赦無くご指摘いただければ幸いです。
※サーバレスでピンとこない方は[こちら](https://qiita.com/isacRU/items/fe4751603d3da32b2daf#%E3%82%B5%E3%83%BC%E3%83%90%E3%83%AC%E3%82%B9%E3%81%A3%E3%81%A6%E3%81%AA%E3%81%81%E3%81%AB)をご覧ください。

# DynamoDBを作成
DynamoDBダッシュボード＞テーブルの作成
<img width="906" alt="スクリーンショット 2020-01-07 21.10.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43096/c520958d-eaa3-7f88-1206-000999759148.png">

概要タブのARNはインラインポリシー作成時に使いますので、コピーしときます
<img width="927" alt="スクリーンショット 2020-01-07 21.11.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43096/1c221649-03fe-850e-6cfe-c5128d873c25.png">

# IAMでロールとインラインポリシーの作成
IAMダッシュボード＞ロール＞ロールの作成
<img width="1431" alt="スクリーンショット 2020-01-07 20.00.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43096/8cea3fee-9494-42c7-e0b9-55d3db49110e.png">

AWSサービス＞Lambda＞次のステップ
<img width="982" alt="スクリーンショット 2020-01-07 20.01.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43096/b8b3aae8-1854-2649-4b81-cdda33d2ede6.png">

AWSLambdaExecute選択＞次のステップ
<img width="969" alt="スクリーンショット 2020-01-07 20.02.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43096/db8366c3-35f7-15b6-17dc-3b1fdcac6cfa.png">

次のステップ
<img width="969" alt="スクリーンショット 2020-01-07 20.03.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43096/5cd5e7bc-b9ec-41ea-4490-2e1cf96def77.png">

ロール名入力＞ロールの作成
<img width="981" alt="スクリーンショット 2020-01-07 20.04.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43096/975c8cfe-f83e-a43d-581c-b0e13401cc0a.png">

インラインポリシーの作成は[ここ](https://qiita.com/isacRU/items/f5a16683331779805a1b#%E4%BD%9C%E6%88%90%E3%81%97%E3%81%9F%E3%83%AD%E3%83%BC%E3%83%AB%E3%81%A7%E3%82%A4%E3%83%B3%E3%83%A9%E3%82%A4%E3%83%B3%E3%83%9D%E3%83%AA%E3%82%B7%E3%83%BC%E3%81%AE%E4%BD%9C%E6%88%90)を参考にしてください。
ちなみに今回はDynamoDBテーブルに書込みをするだけなので、アクション(権限)はPutItemだけでOKです。


# S3バケットの作成
S3ダッシュボード＞バケットを作成する＞バケット名を入力＞作成
<img width="1097" alt="スクリーンショット 2020-01-07 20.13.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43096/ad05f048-c6fc-ffc4-64c8-fc945d8c2e52.png">

# Lambda関数の作成と設定
- Lambdaダッシュボード＞関数の作成
- 関数名入力＞既存ロール選択(上記で作成したロール)
<img width="1288" alt="スクリーンショット 2020-01-07 20.29.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43096/bd360e74-5d93-e3a1-b7e6-1bbbb9c0443b.png">

- トリガーを追加＞S3選択＞バケット名選択(上記で作成したやつ)
- イベントタイプ選択＞サフィックス入力＞追加
<img width="817" alt="スクリーンショット 2020-01-07 20.33.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43096/67db0e3a-5cb9-b7ae-2caf-51a268101fdd.png">
ソース

```javascript:indedx.js
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const documentClient = new AWS.DynamoDB.DocumentClient();

exports.handler = async (event) => {
  
  const { name } = event.Records[0].s3.bucket;
  const { key } = event.Records[0].s3.object;
  
  const getObjectParams = {
    Bucket: name,
    Key: key
  };
  
  try {
    const s3Data = await s3.getObject(getObjectParams).promise();
    const usersStr = s3Data.Body.toString();
    const usersJSON = JSON.parse(usersStr);
    console.log(`Jsonファイル取得結果 ::: ${usersStr}`);
    
    //取得した文のJson結果をDynamoDBテーブルに追加する
    await Promise.all(usersJSON.map(async user => {
      const { id, firstname, lastname } = user;
      
      const putParams = {
        TableName: "JsonDataFromS3",
        Item: {
          id: id,
          firstname: firstname,
          lastname: lastname
        }
      };
      
      await documentClient.put(putParams).promise();
      
    }));
      
  } catch(err) {
      console.log(err);
  }
};
```

# 結果の確認
S３ダッシュボード＞今回使うバケットを選択＞ファイル追加＞アップロード
<img width="1098" alt="スクリーンショット 2020-01-07 21.49.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43096/a7067b3a-90ab-e051-a224-58b420a62791.png">
使用したJson内容

```json:JsonDataFromS3.json
[
    {
      "id": "5ac6be6b-8064-4159-9de6-89178a9f8a54",
      "firstname": "Matt",
      "lastname":"Hansen"
    },
    {
      "id": "4b912da3-66aa-45c1-a87f-9f79a256e570",
      "firstname": "Brad",
      "lastname":"Lunsford"
    },
    {
      "id": "8ef0c795-42d4-439d-962e-75afe957e069",
      "firstname": "Jeremy",
      "lastname":"Kane"
    }
  ]
```

DynamoDBテーブルの中身がS3にアップロードしたJsonファイル通りの内容になっていることを確認
<img width="922" alt="スクリーンショット 2020-01-07 21.55.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43096/077eef81-786c-078e-47ff-6da8788a81b4.png">

最後に
次はサーバレスでRESTful ウェブサービスを作っていきたいと思っています。
Lambda(NodeJS)+API GateWay+DynamoDB+Cognitoを組み合わせる予定です。