AWS Lambda DynamoDB でCRUD

構成

フロントエンド : Vue.js
AWS(インフラ) : S3API GatewayLambdaDynamoDB

構成はこんな感じです。
DBはDynamoDB、アプリケーションサーバの代わりにlambdaを使ってサーバレスにする。
lambdaプログラムをAPI Gatewayと連携し、APIとして呼べるようにする。
Webサーバのように使えるS3にフロントエンドのプログラムをデプロイする。

画面

画面こんな感じです。

手順

以下のような手順で作成します。
が、死ぬほど長くなってしまったので、本記事は①②までとしました!!
③〜⑤は、後ほど作成します!カミングスーン!

①DynamoDBテーブルを作成する

1.1 テーブル作成
1.2 カラム作成

②GETメソッド作成(CRUDのR)

Lambda関数作成
API Gateway作成
Vue.js作成

③POSTメソッド作成(CRUDのC)

Lambda関数作成
API Gateway作成
Vue.js作成

④Deleteメソッドの作成(CRUDのD)

Lambda関数作成
API Gateway作成
Vue.js作成

⑤PUTメソッドの作成(CRUDのU)

前提条件

AWSアカウント作成ずみであること
(フルアクセス権限のIAMユーザを作ってそこから操作することをお勧めします。)

① DynamoDBテーブルを作成する

※ここからAWSマネジメントコンソール画面を操作していきますが、
今後、画面のレイアウト、表示項目などが変わる可能性があります!
本記事と、実際の画面が違った場合は、心で感じ取って、うまく進めてください!!

1.1 テーブル作成

AWSコンソールへログインし、DynamoDBの画面から「テーブル作成」を開く

テーブル名(作ろうとしているアプリ名が良いですかね)とプライマリーキーを入力し、
「作成」を押下する

1.2 カラム作成

画面左のメニューから「テーブル」をクリック
作成したテーブル名クリック
「項目」タブを開き
「項目の作成」をクリック

「+」をクリック、「Append」をクリック、「String」を選択

アプリに必要なカラム名を追加する。

同様の操作で必要なカラムを全て作成する。

それぞれのカラムに適当なデータを入力します。

「保存」ボタンを押下します。
※データを入れてあげないと下のような赤文字のエラーが出ます。

これでDBは完成です。

② GETメソッド作成(CRUDのR)

ここからCRUDごとに処理を作っていきます。

2.1 Lambda関数作成

AWSコンソールからlambda画面へ行き、「関数の作成」をクリックする

「一から作成」を選択(デフォルト)、
関数名を入力(今回はgetメソッドなので-getとする)
「Node.js」を選択(デフォルト)
「関数の作成」をクリックする

このような画面に遷移すればOKです。

2.1.1 アクセス権限設定(IAMロール)

作成したlambda関数は現時点でDynamoDBにアクセスできません。

(上記の作成手順の時に「アクセス権限」の設定がまだ行っていなかった為)
従って、「アクセス権限」の設定を行います。

作成したlambda関数画面から「アクセス権限」タブを開き、ロール名をクリックします。
このIAMロールはlambda関数作成時に自動で作られています。

IAMロール画面が開き、「ポリシーをアタッチします」をクリック

検索窓に「dynamo」くらいで検査し、「AmazonDynamoDBFullAccess」を選択する
「ポリシーのアタッチ」をクリックする

以下メッセージが出れば、ロール設定完了です。

2.1.2 Lambda関数内にGet処理を書く

いよいよlambda関数にgetメソッドを書いていきます。

index.js

const AWS = require('aws-sdk')
const dynamo = new AWS.DynamoDB.DocumentClient()

exports.handler = (event, context, callback) => {
    const httpMethod = event.httpMethod
    const params = {
        // ここで作成したDynamoDBテーブル名を指定
        'TableName': 'lambdaapp-persons'
    }
    dynamo.scan(params, function (err, data) {
        const response = {
            statusCode: 200,
            body: JSON.stringify(data.Items)
        }
        callback(null, response)
    })
};

コードエディタの部分にコードを貼り付け、「Deploy」をクリックする

2.1.3 Lambda関数をテストする

「テストイベントの選択」プルダウンより「テストイベントの設定」を選択

任意のイベント名を入力し、「作成」をクリック
※Getメソッドではパラメータは特にないので、エディタの操作は不要

作成したテストイベントが選択された状態で「テスト」をクリック

うまくいくと「実行結果:成功」と表示されます。

結果の詳細を見てみると、DynamoDBに登録したデータが取れているのが分かります。

2.2 API Gateway作成

2.2.1 API Gateway作成

先ほど作成したGetメソッドをフロント側から呼び出せるようにAPI Gatewayを作成します。

API Gateway画面から「API 作成」をクリック

API Typeを選択します。「REST API」の「構築」をクリック

「新しいAPI」(デフォルト)を選択、
API名を入力(1つのAPIでCRUD全て追加するので、ここではget、postなどは入れていません)、
「APIの作成」をクリック

2.2.2 メソッドの作成

作成したAPI Gatewayの画面に遷移します。
「アクション」から「メソッドの作成」をクリック

プルダウンから「GET」を選択し、チェックマークをクリック

「GET – セットアップ」画面が現れます。
統合タイプ「lambda関数」を選択し、先ほど作成したlambda関数名を入力
「保存」をクリック

下記メッセージはOKです。

Lambda関数を見てみると、上記「権限を与える」操作によりAPI Gatewayがトリガーとして追加されます。

2.2.3 メソッドをテスト

作成したAPI Gatewayメソッドからlambda関数が実行できるかテストします。

「テスト」をクリック

「テスト」をクリック!!

ボタンの下にテスト結果が表示されます。
ステータス:200であればOK。

bodyの所にDynamoDB作成時に作ったデータが入っています。

2.2.4 CORSの有効化

CORSとは!
Cross-Origin Resource Sharing(オリジン間リソース共有)の略で
異なるオリジンとの通信ができるようにブラウザへ指示する仕組みです。
今回の例で言うと、HTMLファイルをS3にアップロードして、S3から発行されたURLでブラウザに表示します。
さらにHTMLファイルの中にAPI GatewayのURLを書いて、メソッドを呼び出しています。
①S3のURLと②API GatewayのURLが異なるオリジンということになり、
それらを同時に扱うためにCORSが必要という事ですね。
参考

「アクション」から「CORSの有効化」をクリック

GETメソッドに✅が入っていることを確認し、「CORSを有効にして既存のCORSヘッダーを置換」をクリック

「はい、既存の値を置き換えます」をクリック

全ての項目に✅が付き、エラーが出なければOK

2.2.5 メソッドをデプロイ

「アクション」から「APIのデプロイ」をクリックします。

デプロイされるステージはプルダウンから「新しいステージ」を選択
ステージ名に今回は「dev」と入力。※開発用だったらdev、商用だったらprodといった具合に分けるようですね
ステージの説明、デプロイメントの説明の入力は任意
「デプロイ」をクリック

デプロイが成功すると、APIのURLが表示されます。先ほど入力したステージ名が末尾に入っています。

2.3 Vue.js作成

2.3.1 ローカルでVue.jsを作成

まずはローカル環境にindex.htmlを作成し、vue.jsで書いていきます。
[作成したAPI GatewayのURL]の箇所をCtrl + Fで探して頂き、作成したAPIのURLを書きます。
ソースはGithubでも参照いただけます。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Persons</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
</head>
<body>
  <div id="app">
    <div class="container mt-5">
      <div class="row">
        <div class="col-md-12">
          <h1>{{ title }}</h1>
          <h1>{{ psersons }}</h1>
          <p>Please add persons whom you like or respect, and describe them in detail.</p>
          <table class="table">
            <thead class="thead-dark">
              <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Description</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="person in persons">
                <td>{{ person.id }}</td>
                <td>{{ person.name }}</td>
                <td>{{ person.description }}</td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script>
    const vue = new Vue({
      el: "#app",
      data: {
        title: 'Persons',
        form: {
          id:'',
          name:'',
          description:''
        },
        persons: '',
        editIndex: -1,
        createFlag: true
      },
      mounted(){
        axios
          .get('[作成したAPI GatewayのURL]')
          .then(response => (this.persons = JSON.parse(response.data.body)))
          .catch(function(error){ 
            alert('Personsデータの取得に失敗しましたっ!\n(・Д・)ナンダッテェ!!' );
            console.log(error);
          });
      }
    });
  </script>
</body>
</html>

HTMLファイルをブラウザで実行すると以下のような画面が表示されます。
(ドラえもんだけだと寂しいので、もう1レコード追加してみました。: Personsのタイトルは無視してください。)

2.3.2 作成したVue.jsをS3へアップロード

まずS3バケットを作成します。
S3画面へ飛び、「バケットを作成」をクリック

バケット名を入力します。下へスクロール。

「パブリックアクセスを全てブロック」の✅を外し、下2つに✅をつける。
なかなか分かりづらいですが、要するにS3にあるHTMLファアイルをインターネットから参照できるようにしています。
さらに下へスクロール。

バケットのバージョニングは有効にすると、間違ってアップロードした時なんかに
元に戻せたりするみたいですね。お好みでどうぞ。
筆者はデフォルトの「無効」とします。

さらに下へスクロールし、「バケットを作成」を押下する。

正常に作成されました、と言うメッセージが表示されます。
作成したS3バケットをクリック

下図のエリアにhtmlファイルをドラッグ&ドロップする

HTMLファイルが表示されます。下へスクロール

「アップロード」をクリック

アップロード成功しました。

作成したバケットの画面に戻り、
アップロードしたHTMLファイルに✅をつけ、
「アクション」から「公開する」をクリック

「公開する」をクリック

正常に公開されました。とメッセージが表示されます。

再びバケット画面に戻り、HTMLファイルをクリック

「オブジェクト URL」をコピー

URLをブラウザで実行して、動作確認

参考記事

公式: チュートリアル: Lambda と DynamoDB を使用した CRUD API の構築

以下は、画面設定の分かりやすい画像が含まれています。

API Gateway + LambdaでREST API開発を体験しよう [10分で完成編]

【サーバーレス】serverless framework 入門

CognitoでWebアプリケーション(not SPA)にログインさせたい時、何を作らなくてはならないのか?

SPAとWebアプリケーションでCognitoの使い方はどう変わるのか?

Cognito IDプールとAuth0を連携させてWebアプリケーションからAWSを操作する画面を作った話

【AWSによるサーバーレスアプリの基礎#2】API GatewayとLambdaの基礎

【AWSによるサーバーレスアプリの基礎#3】HTTPメソッドとリソース

【AWSによるサーバーレスアプリの基礎#4】LambdaでDynamoDBの利用

【AWSによるサーバーレスアプリの基礎#6】S3によるフロントエンドのデプロイ

【AWSによるサーバーレスアプリの基礎#7】Lambdaのレイヤー