🤔

DynamoDB + AppSync設計パターン(備忘録)

2021/03/01に公開

はじめに

プロジェクトでDynamoDB + AppSyncを利用したサービスの設計をしたので、その時のハマりポイント等を備忘録として残します。

DynamoDB設計の備忘録

DynamoDBに対してScanすることは避ける。
なぜ??? → テーブルを総ナメにする為。

設計ポイント

1. 関連するデータをまとめる
DynamoDBはできるだけ、少ないテーブルを維持する必要がある。

2. GSI(グローバル・セカンダリ・インデックス)を利用する
GSIを利用すると、同一テーブルでPKを切り替えることができます。つまり、特定のGSIを作成することで、メインのテーブルでサポートできるクエリとは異なるクエリを有効にできるのです。これがすごく使えます。

ユースケース : 例えばoperation[query]を使用している前提で、SKを範囲指定し検索した結果をfeachしたい場合、メインのテーブルのPKに対し一意になるような値[例えばuuid等]を設定していると、通常の[query]で範囲検索をしfeachすることができません。その場合、テーブルにある他のカラムをPKとしたい時にGSIが利用できます。

RDBMSとDynamoDBの違い

RDBMS
クエリの最適化は、スキーマ設計に依存しないので、正規化が重要です。

DynamoDB
よく使われるクエリを早く問い合わせできるようにスキーマを設計します。

AppSyncにおけるスキーマ/リゾルバ設計の備忘録

DynamoDBに対する操作ができるOperationの一覧

GetItem
Partation keyを条件として指定し、一件のアイテム取得

PutItem
1件のアイテムを書き込む

Update
1件のアイテムを更新

Delete
1件のアイテム削除

Query
Partation KeyとSort Keyの複合条件にマッチするアイテム群を取得

BatchGet
複数のプライマリキーを指定して、マッチするアイテム群を取得

Scan
テーブルを総ナメにする

重要 : DynamoDBに対するQuery or Scanのオペレーションでは最大で1MBのデータしか取得できない。
その為、Scanを利用してしまうと、項目内のデータサイズによっては全て取得しきれない可能性がある(テーブル内データを総ナメにする為)。

  • では、どうするのか
    答えは、Projectionの利用です。
    DynamoDB は、デフォルトですべての項目属性を返します。すべての属性ではなく、一部の属性のみを取得するには、Projectionを使用します。

  • projectionは分かったけど、どう設定するのか
    まず、DynamoDB側でインデックスの設定を行います。
    その際に[属性]という項目があるので、必要な項目のみ記載します。記載されない項目は、削ぎ落ちます。つまり、ここがインターフェースになるということです。

次にAppSync側の設定です。
Operationに[Query]を利用している場合、リゾルバ内のオプション項目[select]を使用し、
ALL_PROJECTED_ATTRIBUTES]を設定します。
ALL_PROJECTED_ATTRIBUTESとは、インデックスにクエリを実行する場合のみ使用できます。インデックスに投射されたすべての属性を取得します。つまり、これで、見たい項目のみに絞り込みができます。

[設定例]

"select" : "ALL_PROJECTED_ATTRIBUTES"

おまけ (AppSyncに対する認証はどうするべき・・)

いくつかある認証方式の中で、よく使われるものを抜粋

[API_KEY認証]

  • 利用方法
    クライアント側に認証用のAPI_KEYを埋め込みApp Syncを利用します。

  • 問題点
    API_KEYが発行されるとdefaultで7日後に有効期限が切れます。
    API_KEYは、最大 365 日間有効に設定可能で、該当日からさらに最大 365 日、既存の有効期限を延長できます。
    API_KEYは、パブリック API の公開が安全であるユースケース、または開発目的での使用が推奨されます。

[AMAZON_COGNITO_USER_POOLS認証]

  • 利用方法
    GraphQL オペレーションを送信するときに authorizaton ヘッダーで AWS AppSyncに送信します。

引用

DynamoDB Projection
AppSync Projectionの利用

Discussion