タイトルがわかりにくく、長くてすみません。
やろとしていることは、
(CQRSとして)テーブルAに入ったデータを加工してテーブルBに入れる。
その時に、テーブルBのテーブル名をうまく扱えないないかと調べた時の情報。
Amazon DynamoDB Streams とAWS Lambdaを使った場合で Amplify CLIで作成しているテーブル名の扱い方です。
この記事で記載しないこと
- DynamoDB Streamsの使いかた
- AmplifyでのDynamoDB Streams の使いかた
- DynamoDB Streams を使ったLambda functionのサンプル
Lambda における環境変数
AWS マネジメントコンソールのLambdaの環境変数を抜粋
環境変数キー | 環境変数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のイベントハンドラー
イベントハンドラーのソース
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データのサンプル
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の1つである 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 が取得できる
実行サンプル
取り出しサンプルソース
https://paiza.io/ja/projects/new?language=javascript を使ってみる
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に書き込むテーブル名で使う
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 のドキュメントを参照