AWS Amplify CLIで生成したテーブルをAmazon DynamoDB Triggers を使い DynamoDB StreamsとAWS Lambdaを連携する時のテーブル名

タイトルがわかりにくく、長くてすみません。
やろとしていることは、
（CQRSとして）テーブルAに入ったデータを加工してテーブルBに入れる。
その時に、テーブルBのテーブル名をうまく扱えないないかと調べた時の情報。
Amazon DynamoDB Streams とAWS Lambdaを使った場合で Amplify CLIで作成しているテーブル名の扱い方です。

## この記事で記載しないこと
- DynamoDB Streamsの使いかた
- AmplifyでのDynamoDB Streams の使いかた
- DynamoDB Streams を使ったLambda functionのサンプル

## Lambda における環境変数

AWS マネジメントコンソールのLambdaの環境変数を抜粋
<img src ="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1482752/851eb76b-1e5b-eeb9-49e0-b501838e2b58.png"  width ="400" />

|環境変数キー  |環境変数value  |利用方法  |
|---|---|---|
| DDB_TABLE_TABLE_B |tableB-qad7xxxxxxu-dev  |process.env.DDB_TABLE_TABLE_B|
| ENV |dev  |process.env.ENV|

`Amplify cli` では、`amplify add function` で環境変数を追加（設定）できます。
詳しくは、ドキュメント https://docs.amplify.aws/cli/function/env-vars/ を参照。


## Lambdaのイベントハンドラー

### イベントハンドラーのソース

```js
exports.handler = async (event, context) => {

  console.log('event:', event);
  console.log('context:', context);
  return { body: 'Successfully created or updated item!' };
};
```

### 引数のevent内を参照

DynamoDB Streams では トリガー元のテーブル名は、Lambda Function の引数  event に保持しています。

- eventの中に入っているjsonデータのサンプル

```json
event: {
   Records: [
     {
       eventID: '0c1a636cb175308632ca6d137c0c8010',
       eventName: 'INSERT',
       eventVersion: '1.1',
       eventSource: 'aws:dynamodb',
       awsRegion: 'ap-northeast-1',
       dynamodb: [Object],
       eventSourceARN: 'arn:aws:dynamodb:ap-northeast-1:xxxxx:table/tableA-AppSyncID-dev/stream/2021-12-12T15:58:15.123'
     }
   ]
}
```

- eventSourceARN が トリガー元となったDynamoDB のテーブルARNです
- arn:～ の、tableA が Amplify での schema.graphql での `type tableA @model{}` に相当します
- arn:～ のAppSyncID は20-30の英数字である AWS AppSync ID です。バックエンドのenvごとに変わる
- arn:～ のdev は、amplify env list で表示されるうちの envの１つである env: dev を示す

以上から、eventSourceARN の中身を分解することで、schema.graphqlで定義したテーブル（type）名がわかる。

## ARNの情報からtableAのテーブル名を導く

- Amplify CLIで作成されるDynamoDBテーブルは、schema.graphqlのテーブル定義名 + "-" + AWS AppSync API ID + "-" + process.env.ENV で扱える

### eventSourceARN を分解して

- event.Records[0].eventSourceARN でarnの行は取得できる
- eventSourceARN は、 '/' で分解して、テーブル名を取り出す
- `eventSourceARN.split(':')[5].split('/')[1]`  => 'tableA-AppSyncID-dev' が取得できる
- `eventSourceARN.split(':')[5].split('/')[1].split('-')[0])` => 'tableA' が取得できる
- `eventSourceARN.split(':')[5].split('/')[1].split('-')[1])` => AppSyncID が取得できる


### 実行サンプル

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1482752/34b11903-9444-7b39-e7c2-86c02fe61bea.png" width ="800" />


#### 取り出しサンプルソース

https://paiza.io/ja/projects/new?language=javascript を使ってみる

```js
process.stdin.resume();
process.stdin.setEncoding('utf8');
// Your code here!

const eventSourceARN = 'arn:aws:dynamodb:ap-northeast-1:xxxxx:table/tableA-AppSyncID-dev/stream/2021-12-12T15:58:15.123'
console.log(eventSourceARN.split(':')[5].split('/')[1]);
console.log(eventSourceARN.split(':')[5].split('/')[1].split('-')[0]);
console.log(eventSourceARN.split(':')[5].split('/')[1].split('-')[1]);
```

## tableBのテーブル名を導く

先のコードのように、tableAとAppSyncID を取得したように、

```
const eventSourceARN = 'arn:aws:dynamodb:ap-northeast-1:xxxxx:table/tableA-AppSyncID-dev/stream/2021-12-12T15:58:15.123'
const appSyncAPIID = eventSourceARN.split('/')[1].split('-')[1];
const tableBName = "tableB" + "-"+ appSyncAPIID + "-" + process.env.ENV;
console.log(tableBName);
```
上記の結果より `tableB-AppSyncID-dev` が出力できる

以下のように、replaceでも良い

```
const tableBName = eventSourceARN.split(':')[5].split('/')[1].replace("tableA","tableB"));
```

## DynamoDBに書き込むテーブル名で使う

```js
const aws = require('aws-sdk');

const eventSourceARN = 'arn:aws:dynamodb:ap-northeast-1:xxxxx:table/tableA-AppSyncID-dev/stream/2021-12-12T15:58:15.123'
const appSyncAPIID = eventSourceARN.split('/')[1].split('-')[1];
const tableBName = "tableB" + "-"+ appSyncAPIID + "-" + process.env.ENV;

const docClient= new aws.DynamoDB.DocumentClient();
const ddbdcParams = {
  TableName: tableBName ,
  Item: {
    "id": "12345",
    "name": "Taro"
  }
};
docClient.put(ddbdcParams);
```


### 用語
DynamoDB Streamsについては、
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Streams.Lambda.html のドキュメントを参照