概要
Amplifyで有効期限付きのデータを扱いたくなったので、DynamoDBのTTL設定ができないか調べたところ設定方法があるようなのでメモを。
API作成
amplify cliのおなじみのコマンドでapiを作成します。
amplify add api
schema.graphqlは以下のような感じ。(サンプルのやつにttlを追加)
type Todo @model {
id: ID!
name: String!
description: String
ttl: AWSTimestamp!
}
APIのカスタマイズ
公式の記事に従ってカスタマイズ設定を施す。
amplify override api
/amplify/backend/api/フォルダの下に「override.ts」というファイルが生成されるので以下のようにttl設定を行う。
("Todo"の箇所を自分の環境に合わせて書き換える。)
import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper';
export function override(resources: AmplifyApiGraphQlResourceStackTemplate) {
resources.models["Todo"].modelDDBTable.timeToLiveSpecification = {
attributeName: "ttl",
enabled: true
}
}
デプロイ
エラーが起こらないことを祈りつつ、心を込めてコマンドを打つ。
amplify push
無事、デプロイが完了するとDynamodbにTodoテーブルが作成される。
動作を見てみる
データ投入
確認方法は何でも良いが、手軽に試したいのでAppSyncのコンソールからmutation実行。
mutation MyMutation {
createTodo(input: {id: "001", name: "hoge", description: "desc", ttl: 1668608700}) {
id
}
}
TTL属性はエポック時間形式で指定する必要がありますが、計算が面倒だったので以下のようなEpochConveterを利用させていだだきました。
公式の記事にも紹介されているし、怪しいものではないはず。
結果の観測
無事、データ投入ができたので有効期限経過後にデータが削除されるのを待つ。
...
...
が、時間が過ぎても消される様子がない。。。
調べてみると、
「TTL タイムスタンプの有効期限が切れると、DynamoDB は書き込みスループットをまったく消費せずに 48 時間以内にテーブルから項目を削除します。」
って書いてますね。
有効期限後に即座に削除されることを保証するものではないみたい。orz
TTLは場合によっては48時間以上の時間を要する事例もあるようなので、レコードの削除が即座に行われることを期待するようなサービスでは地道にCloudWatch EventsでLambda定期実行して該当レコードを削除していく方法を取ることになりそう。
もちろん、TTL設定だけで不要なレコードが削除されるのは非常に便利なので、使い所は要件次第ですが。
その他
ちなみに、AmplifyでTTL設定するのにgraphql-ttl-transformerというライブラリがあるようですが、こちらを試したところ以下エラーでamplify pushに失敗したため断念しました。
使ったamplify cliのバージョンはv10.4.1。
Unable to import custom transformer module(graphql-ttl-transformer).
🛑 You may fix this error by editing transformers at graphql-ttl-transformer/transform.conf.json
まとめ
AmplifyのAPIのカスタマイズ機能を使ってDynamoDBのTTL設定を試してみました。驚くほど簡単に設定ができてしまいますね。
今回調べてみたoverride apiだけでも他に色々ありそうなので、機会があれば試してみたいと思います。