無知から始めるイベントドリブンアーキテクチャ ~実践編~

# 【概要】

以前、[「無知から始めるイベントドリブンアーキテクチャ ~導入編~」](https://qiita.com/Suzuki_Cecil/items/a51d353c73e9277f46d8) にて無知な筆者がイベントドリブンアーキテクチャ(Event Driven Architecture)の概要を記事にさせていただきました。
本記事ではAWSのDynamoDB Streamを活用した簡単なイベントドリブンアーキテクチャを構築する過程をまとめさせていただきます。

# 【対象読者】

1. 今後イベントドリブンアーキテクチャについて学習を始める方
2. AWSを触ったことない or ほぼ触ったことない方

# 【構築するアーキテクチャの概要】

イメージとしてはECサイトのような注文システムを考えてください。

![EDA.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/edb385bd-256e-d68e-5a29-ca7da1f06b9a.png)

システムは以下のような動作を行います。

1. ユーザーが商品を注文するとDynamoDBの注文テーブルにレコードが挿入
2. 注文レコードが挿入されるとDynamoDB StreamによりLambda関数が実行されます
3. Lambda関数はCloud Watchに注文ログを残します

※わざわざLambdaを経由してロギングする必要あるか？というのは一旦無視していただけると幸いです。

# 【デモ】

これから構築するアーキテクチャのデモです。本来であればアプリゲーションが注文テーブルにレコードを挿入するかと思いますが、今回はデモですので手動でレコードを挿入します。

注文テーブルにレコードを挿入すると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/ffb1735d-12ac-e549-d311-92f6338f4eef.png)

CloudWatchにログが残ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/d908cd33-b656-4fa8-6f7b-6095d7bb35a5.png)

（静止画だと分かりにくいので余裕があればgifにします。）

# 【構築手順】

AWSを触ったことない人 or ほぼ触ったことない人向けに手順をまとめますので説明が不要なところは読み飛ばしてください。

## 1. はじめに

[AWSマネジメントコンソール](https://ap-northeast-1.console.aws.amazon.com/console/home?region=ap-northeast-1#)にログインします。アカウントを持っていない方はアカウントを作ってください。
ログインが成功すると以下のような画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/91328430-6ca2-724c-cdd4-5842a0da22f1.png)

## 2. DynamoDB

まずはDynamoDBにテーブルを作り、テーブルのストリームを有効にします。

1. AWSマネジメントコンソールのヘッダーにあるサービスを押下するとAWSのサービス一覧が表示されますので、テキストボックスにDynamoDBと入力し、サジェストに表示されるDynamoDBを選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/024d19fe-0bc3-71ae-d0fd-9b0dfbc7576d.png)
2. DynamoDBのトップページに遷移します。まずはテーブルを作りますので、テーブルの作成を押下してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/87721e19-1f55-86a9-dfb2-00844ba342fd.png)
3. テーブルの作成画面に遷移します。テーブル名とプライマリキーは下記の通り設定してください。（DynamoDBを初めて触る方はチュートリアルを選択することを推奨します）

    テーブル名 : Order
    プライマリキー : ItemName, ClientName
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/e68d42a8-036a-d081-f96c-18d981a894cd.png)
4. テーブルの作成が完了すると以下のような画面が表示されます（テーブルの作成には３０秒程度かかります）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/1ab86bf5-8ba7-0831-a253-80c555727fde.png)
5. 次にDynamoDB Streamを有効にします。ストリームの管理を押下するとポップアップが表示されますので、新旧イメージを選択して有効化を押下してください。有効化が完了しましたらDynamoDBの設定は一旦終了となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/e72671b8-1bdd-127d-0ad7-516fc7a5616e.png)


## 3. IAMロール

次にOrderテーブルにレコードが挿入されると実行されるLambda関数のIAMロールを作成します。

1. DynamoDBの時と同じようにIAMのトップページに遷移します。ヘッダーにあるサービスを押下するとAWSサービスの一覧が表示されますので、テキストボックスにIAMと入力し、サジェストに表示されるIAMを選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/d9e40151-3d8b-7580-f043-a5154a683e93.png)
2. IAMのトップページに遷移しますので、サイドバーのロールを選択してください。IAMロールを新しく作りますので、ロールの作成を押下してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/dbb076b6-76d3-a282-6ed5-8de8fdf3d75f.png)
3. Lambdaのロールを作りますので、Lambdaを選択して次のステップを押下してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/9db5c539-6a99-3196-6be0-90a6f54633d2.png)
4. 次にロールのポリシーを設定します。ロールにアタッチするポリシーは **AmazonDynamoDBFullAccess**, **AWSLambdaDynamoDBExecutionRole** です。ポリシーを選択したら、次のステップを押下してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/d96f9bf4-9a33-a019-e3a0-13cda6b130eb.png)
5. 次にタグの設定に移りますが、今回はタグの設定を行わないため次のステップを押下してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/54c82888-a8d8-1165-ee2d-91c1e8f01eb7.png)
6. 最後にIAMロールの確認画面に移ります。ここでロール名を入力できますので、 **orderLogger** とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/5214733f-8f1b-06c9-6731-0cc855544b2f.png)
7. IAMロールの作成が完了したら、次はLambda関数の作成です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/aba6f4a1-0fe9-eb38-3da5-cd4ccf8f0ced.png)


## 4. Lambda

次にOrderテーブルにレコードが挿入されると実行されるとLambda関数を作成します。この関数の実行ロールに先ほど作った **orderLogger** を設定します。

1. DynamoDBの時と同じようにLambdaのトップページに遷移します。ヘッダーにあるサービスを押下するとAWSサービスの一覧が表示されますので、テキストボックスにLambdaと入力し、サジェストに表示されるLambdaを選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/2272d5c8-115c-31d7-42c3-42a17eeb4a3e.png)
2. Lambdaのトップページに遷移します。関数を作りたいので、関数の作成を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/22e31a28-40ae-248b-25d9-eccabf2db6c9.png)
3. 関数の作成画面に遷移します。関数の設定は以下の通りです。設定したら関数の作成を押下してください。

    関数名 : loggingOrder
    ランタイム : Node.js 10.x
    実行ロール : 既存のロールを使用する
    既存のロール : orderLogger
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/39421897-65fd-70e8-58ea-c3f7798bce49.png)
4. 関数を作成すると以下のような画面が表示されます。関数のトリガーを設定するので、サイドバーのトリガーの追加からDynamoDBを選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/061b947f-a9d5-c3e6-141d-7c11fdc1d6e7.png)
5. 同画面にて下方にスクロールするとトリガーの設定が変更できます。トリガーの設定は以下の通りです。設定したら追加を押下してください。

    DynamoDBテーブル : Order
    バッチサイズ : 100
    開始位置 : 最新
    トリガーの有効化 : チェックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/7ea3fa9f-9ac4-4e5f-3983-ff653f055463.png)
6. 同画面にて上方にスクロールし、loggingOrderを選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/1541eb11-5157-607b-91c9-986f5d909f34.png)
7. 同画面にて下方にスクロールすると、関数コードを編集するためのエディタがあります。エディタにて画像下に記載のコードをコピペしてください。コピペしましたら右上にある保存ボタンを押下してください。これでイベントドリブンアーキテクチャの構築は完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/f1d14e06-d3f8-8c50-60df-08d179fb81f4.png)

``` index.js
console.log('Loading function');

exports.handler = async (event, context) => {
    for (const record of event.Records) {
        console.log(record.eventID);
        console.log(record.eventName);
        console.log('DynamoDB Record: %j', record.dynamodb);
    }
    return `Successfully processed ${event.Records.length} records.`;
};

```

# 【デモ】

![EDA.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/edb385bd-256e-d68e-5a29-ca7da1f06b9a.png)

これで構築が完了しましたので、実際に動かしてみます。本来であればアプリゲーションが注文テーブルにレコードを挿入するかと思いますが、今回はデモですので手動でレコードを挿入します。

1. 再度DynamoDBのページを表示します。項目タブを選択すると現在はレコードが１行もないことが分かります。新たにレコードを挿入しますので、項目の作成を押下してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/95b49c05-c5c9-c903-1fc2-2a82417e7239.png)
2. ポップアップが表示されますので、任意のItemNameとClientNameを入力して保存を押下してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/160fe411-f52c-77af-c3ba-231f98c054ee.png)
3. レコードが作られたことが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/ffb1735d-12ac-e549-d311-92f6338f4eef.png)
4. CloudWatchのトップページを表示してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/9b90ab1e-d27f-911a-8de8-a5d12a2df27d.png)
5. サイドバーのログを選択すると、ロググループに **/aws/lambda/loggingOrder** があります。ロググループ、ログストリームを選択するといくつがログが残っていると思います。その中に画像のようなログがあると思います。もし無かったら、構築が失敗していますので見返してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/d908cd33-b656-4fa8-6f7b-6095d7bb35a5.png)

以上で、注文レコードが挿入されるとDynamoDB StreamによりLambda関数が実行され注文ログが残ることが確認できました。

# 【発展】

今回はイベントドリブンアーキテクチャの構築を経験してみるということで、注文が入るとログが残るという簡易的な構築を行いましたが、例えば以下のように注文が入ると在庫管理システム・発送システム・経理システムなど複数のサービスが実行されるといった構築も可能です。ぜひイベントドリブンアーキテクチャの可能性を模索していただけると幸いです。

![EDA (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375860/45c93fd8-97d7-65cb-c4f1-8758ee6ca8f2.png)