BLOG

R3 Cloud Journey

AWS

Amplify DataStore に新機能 "Selective Sync" が追加されました!

2020-11-03

Amplify DataStore を使っていますか?

Amplify DataStore を使うと、クラウドと連携するアプリケーションを容易に開発することができます。

例えば POS のようにオフラインでも高速に動作する必要があるが、定期的にサーバーサイド(物理サーバーを使用しないので何と表現するのが良いでしょうか・・クラウド側というかバックエンドというかマネージドデータベースというか)へデータを送り、複数の端末で共有したいアプリケーションには Amplify DataStore がまさにオススメです。POSのデータ同期の仕組みをイチから開発するような時代ではないのです。

また、入退室管理のような仕組みにも Amplify DataStore はオススメです。カードキーをかざした人を入室させて良いかはローカルで高速に判定しつつ、履歴はクラウドへ即座に・継続的に同期する、まさにそんな仕組みを作る際には Amplify DataStore の有り難みが身に染みるはずです。

他にも Amplify DataStore が有効なユースケースは多数考えられます。localStorage や Redux を使っているなら、それを Amplify DataStore に置き換えることを検討してみてください。そうです。Amplify DataStore はあらゆる state に適用できる可能性があります。

そんな Amplify DataStore に "Selective Sync" という新機能が追加されました。

Selective Sync は何を解決するのでしょうか? Amplify DataStore についておさらいしながら考えていこうと思います。

まず基本的な Webアプリを作成します。

このブログでも以前に Amplify DataStore の基本について説明した記事を書いたのですが、なぜか Ionic を使ってしまいました。(実際には中身はただの React なのですが)

Amplify DataStore (や AWS AppSync, Amplify)のワークショップ(サンプル)が https://amplify.aws/community/resources にまとめられています。

Angular でも React でも Vue でも好きなものを選んでください。私は今回 Vue を使用することにしました。

そして Amplify DataStore が動作するところまで ワークショップを進めたファイルを https://github.com/r3-yamauchi/amplify-datastore-chatty-vue/tree/DataStore に置いています。amplify init や amplify add api は各々の環境で行う必要がありますが、参考にはなると思います。

この状態で Webアプリを実行すると、DataStore の読み書き、AWS側(DynamoDB)との同期が行えるようになっています。(この記事の状態)

どのようなユーザーでログインしても、全ての人が書き込んだ全てのデータが流れてくるようになっています。

それぞれのユーザー、ブラウザで書き込んだ内容が他方へも即座に反映される

自分が書き込んだ情報を自分にしか見られない(他人が書き込んだ情報は参照できない)ようにするにはどうすれば良いでしょうか。

GraphQL Transformer内で @auth ディレクティブを使う方法があります。

以下のように schema.graphql で model に @auth ディレクティブを付けると オーナー認可することができます。

type Chatty
  @model
  @auth(
    rules: [
      { allow: owner, ownerField: "user", operations: [create, update, delete, read] },
    ])
{
  id: ID!
  user: String!
  message: String!
  createdAt: AWSDateTime
}

このうえで amplify codegen models して amplify push すると、同じユーザーでログインした書き込みのみ参照でき、subscribe されるようになります。

この状態のコードを https://github.com/r3-yamauchi/amplify-datastore-chatty-vue/tree/auth に置きましたので参考にしてください。

(以前の状態との差分は https://github.com/r3-yamauchi/amplify-datastore-chatty-vue/compare/DataStore...r3-yamauchi:auth )

以上は、従来でも実現できました。

"Selective Sync" (以降では syncExpression と呼ぶことにします)を使用すると DynamoDB を条件検索して、一部のデータのみを Amplify DataStore と同期することができるようになりました。

(なお、https://docs.amplify.aws/lib/datastore/conflict/q/platform/js#example で示されている通り、DataStore.configure で maxRecordsToSync や fullSyncInterval というパラメータを渡して DataStore と同期するレコード数に上限をかけたり、同期する間隔を指定することができたようです・・)

syncExpression を試した例が https://github.com/r3-yamauchi/amplify-datastore-chatty-vue/commit/93e4a1386fa99f2e50491c080b946f79c07bb597 です。

モデルに rate という Int 型の項目を追加し、 syncExpression で rate に 5以上 7以下の値を指定した場合のみ クラウド(DynamoDB)と同期するように指示しています。

DataStore.configure({
  syncExpressions: [
    syncExpression(Chatty, () => {
      return (c) => c.rate('gt', 5).rate('lt', 7);
    }),
  ]
});

クラウド(DynamoDB)と同期しないデータは他の端末へは伝搬されません。

この機能はどのようなユースケースで使用できるのでしょうか?

RicardoTwitter に書いていたように @auth ディレクティブではカバーしきれない「マルチテナント」(データの分離)で使用することが思い浮かびます。

また、古いデータは同期せず、直近のデータのみを同期してレスポンスを上げるためにも使用できます。

従来は Amplify DataStore と同期させている DynamoDB テーブルには あまり長期間データを置くことはせず、DynamoDB Streams を使用して他へ書き出し、TTLを設定して一定期間後に削除するのがお決まりのパターンでした。

相変わらず TTLを設定するケースが多いとは思いますが、そのうえで ページ送りや無限スクロールを実装する際に syncExpression を使用できそうです。

Reevaluate expressions at runtime の項で説明されている通り、syncExpression の内容を切り替えることができるからです。

let rating = 5;

DataStore.configure({
  syncExpressions: [
    syncExpression(Chatty, () => {
      return (c) => c.rate('gt', rating);
    }),
  ]
});

    async changeSync() {
      rating = 1;
      await DataStore.stop();
      await DataStore.start();
      this.loadMessages();
    }

また @key ディレクティブを指定すれば DynamoDB に GSI を付け、scan を避けることもできるようです。

Amplify DataStore のパフォーマンスに悩まされていた方はぜひ "Selective Sync" を試してみる価値がありそうです。

ページ送りや無限スクロールを GraphQLクエリ(で AWS AppSyncにアクセスする)で実装するのは、定形パターンではありますが手間がかかります。

Amplify DataStore の方が圧倒的にラクなのではないでしょうか?

Amplify DataStore は決して GraphQL(AWS AppSync)を置き換えるものではないので、まずは Amplify DataStore を使って実装することを考え、足りない部分を DynamoDB Stream や AppSync で補うように考えるのが良いように思います。

AWS
vuejs

アールスリーインスティテュートで、これまでになかった画期的な kintoneカスタマイズサービス gusuku Customine(カスタマイン) を開発しています。 kintone認定アプリデザイン/カスタマイズ スペシャリスト

自社のシステム開発・移行などをご依頼したい方
お客様とともに
作りながら考える
新しいシステム開発
詳しく見る
kintone導入・アプリ開発・カスタマイズにお困りの方
ノーコードでらくらく
kintoneカスタマイズ
詳しく見る
kintoneアプリの
バージョン管理・バックアップ
詳しく見る
kintoneアプリの開発・運用を
強力サポート

詳しく見る
更新情報をメールでお届けします!

kintoneアプリのカスタマイズに役立つ情報や、イベントの情報をメールでお届けいたします。
ご登録をお待ちしております!

R3のご提供サービス
自社のシステム開発・移行などをご依頼したい方
お客様とともに作りながら考える
新しいシステム開発
詳しく見る
kintone導入・アプリ開発・カスタマイズにお困りの方
kintoneをもっと使いやすくする
gusukuシリーズ
詳しく見る
更新情報をメールでお届けします!
kintoneアプリのカスタマイズに役立つ情報や、イベントの情報をメールでお届けいたします。
ご登録をお待ちしております!