React アプリ用に Amazon DynamoDB でユーザ設定テーブルをつくる

こんにちは、広野です。

アプリをつくっていると、ユーザごとのデータ保持が必要になる局面があります。そんなとき、全ユーザの設定データを1つのテーブルでまとめて保持し、かつユーザ単位または設定項目単位で設定データを取り出し易くしたいです。

この度、DynamoDBでそんなユーザ設定テーブルを作ってみたので紹介します。アプリの開発フレームワークは React を使用します。アプリ側でデータをどう扱うか、も本記事のポイントです。

やりたいこと

  • アプリ開発フレームワークは React を使用する。
  • アプリを使用する全ユーザの設定データを1つのテーブルでまとめて保持したい。
  • ユーザの設定データはユーザ単位でまとめて、または設定項目単位で取得できる。
  • アプリ内で設定データを取り扱い易くする。

実現方法

AWSを使ったアーキテクチャ的には以下の図のようになります。本記事では Amazon DynamoDB のテーブル設計やデータの扱い方を主旨としますので、Amazon API Gateway や AWS Lambda についての説明は割愛します。

データ設計

Amazon DynamoDB テーブルにどのようにユーザ設定データを持たせ、アプリ側では最終的にどのようなデータになるのかイメージしてみました。複数ユーザの設定項目、設定パラメータが放り込まれている状態です。

Amazon DynamoDB テーブル内のデータ例

[
  {
    "username": "user01",
    "key": "config-isAbcEnabled",
    "data": true
  },
  {
    "username": "user01",
    "key": "config-nickname",
    "data": "ニックネーム"
  },
  {
    "username": "user01",
    "key": "isLicenseAgreed",
    "data": true
  },
  {
    "username": "user02",
    "key": "config-isAbcEnabled",
    "data": true
  },
  {
    "username": "user02",
    "key": "config-nickname",
    "data": null
  },
  {
    "username": "user02",
    "key": "isLicenseAgreed",
    "data": false
  }
]

アプリ内で欲しいデータ例

上記 Amazon DynamoDB のテーブルから、ログインしているユーザのユーザ名、例えばここでは user01 のデータだけを取ってきたときに、以下のようなデータフォーマットにしたいです。

{
  "config-isAbcEnabled": true,
  "config-nickname": "ニックネーム",
  "isLicenseAgreed": true
}

必要なのはログイン中ユーザの設定データだけなので、ユーザ名は必要ありません。設定項目名と、設定パラメータだけ羅列している状態が理想です。このフォーマットに落とせれば、アプリから設定データを取り出し易いです。

実装例

Amazon DynamoDB テーブル

Amazon DynamoDB テーブルは、シンプルです。username 単位、設定項目名 (key) 単位でデータを取得できるよう、以下のキー設定にします。

パーティションキー ソートキー
username key

必要に応じて、その他オプション設定をして頂ければと思います。

Reactアプリのコード

Amazon DynamoDB からユーザ設定データを取得する

いくつかのコンポーネントで分散してユーザ設定データを取得する可能性があり、関数化しています。いくつかパターンを作ったので、以下は一例です。

//ユーザデータ1格納state定義(DynamoDBから取得直後)
const [userdata1, setUserdata1] = useState([]);
//ユーザデータ取得関数(begins_with条件)
const getUserdataBgn = async (username, key, headerdata) => {
  const res = await axios.post(
    process.env.REACT_APP_USERDATA_URL + "/GetUserdataBgn", //API Gateway エンドポイントは環境変数化
    {
      user: username, //ここで指定した username のデータを取得する
      key: key //ここで指定した key を begins_width 条件にしてマッチしたユーザ設定データを取得する
    },
    {
      headers: headerdata //headerdata にはIDトークンが入り、Cognito Authorizer で使用する
    }
  );
  return res;
};
//ユーザデータ取得
const res = await getUserdataBgn("user01", "config-", headerdata);
setUserdata1(res.data.Items);

ここで、例のように username: “user01”, key: “config-” という条件でユーザ設定データを取得すると、以下のデータが抽出され userdata1 の state に格納されます。

[
  {
    "username": "user01",
    "key": "config-isAbcEnabled",
    "data": true
  },
  {
    "username": "user01",
    "key": "config-nickname",
    "data": "ニックネーム"
  }
]

ユーザ設定データを加工する

このままでは期待しているデータフォーマットではないので、アプリ側でデータを加工します。

//ユーザデータ2格納state定義(加工後)
const [userdata2, setUserdata2] = useState([]);
//Amazon DynamoDBからデータを取得した後、データを整型する
let tempdata = { "dummy": false }; //データが空のときにエラーになってしまうので、ダミーデータを1つだけ入れている
userdata1.map(function(userdata) { //userdata1を、1行ごとに変数userdataに格納し繰り返し処理をする
  tempdata[userdata.key] = userdata.data; //変数userdataの中のkey値をキーに、data値をバリューにしてtempdataに追記
});
setUserdata2(tempdata); //最後にtempdataをuserdata2のstateに格納する

この処理をすることで、期待していたデータをアプリ内 userdata2 の state に格納することができました。(ダミーデータは邪魔ですが)
後はアプリ内で、任意の設定データを使った処理をすることになります。

{
  "config-isAbcEnabled": true,
  "config-nickname": "ニックネーム",
  "dummy": false
}

アプリからユーザ設定データを更新するときには、Amazon DynamoDB テーブルの項目通りにデータをputすればOKです。そこは特段工夫する必要はありません。

まとめ

いかがでしたでしょうか?

ユーザ設定データを扱う方法の一例として、みなさまのお役に立てれば幸いです。

私は React アプリ内でデータを加工しましたが、AWS Lambda 関数の中で加工してあげる方がアプリコードが綺麗になりますね。また、もっとスマートな処理が随所にありそうです。

みなさまは是非この記事をあくまでも参考に、改善して実装してもらえたらと思います。

著者について
広野 祐司

AWSサーバーレスアーキテクチャを駆使して社内クラウド人材育成アプリや教育コンテンツをつくっています。
ReactでSPAを書き始めたら快適すぎて、他の開発言語には戻れなくなりました。React仲間を増やしたいです。
取得資格:AWS認定は7つ、ITサービスマネージャ、ITIL v3 Expert、等
2019, 2020 AWS APN Top engineers 受賞
好きなAWSサービス:AWS Amplify / Amazon Cognito / AWS Step Functions / AWS CloudFormation

広野 祐司をフォローする
クラウドに強いによるエンジニアブログです。
SCSKは専門性と豊富な実績を活かしたクラウドサービス USiZE(ユーサイズ)を提供しています。
USiZEサービスサイトでは、お客様のDX推進をワンストップで支援するサービスの詳細や導入事例を紹介しています。
AWSサーバレスアーキテクチャデータベース
TechHarmony
タイトルとURLをコピーしました