でのバージョニングされたデータソースでの Delta Sync オペレーションの使用 AWS AppSync - AWS AppSync

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

でのバージョニングされたデータソースでの Delta Sync オペレーションの使用 AWS AppSync

注記

現在、主に APPSYNC_JS ランタイムとそのドキュメントをサポートしています。APPSYNC_JS ランタイムとそのガイドをここで使用することを検討してください。

のクライアントアプリケーションは、GraphQL レスポンスをモバイル/ウェブアプリケーションのディスクにローカルにキャッシュすることでデータ AWS AppSync を保存します。バージョン管理されたデータソースと Sync オペレーションにより、お客様は単一のリゾルバーを使用して同期プロセスを実行することができます。これにより、クライアントは大量のレコードを含む可能性のある基本クエリでのローカルキャッシュをハイドレートし、最後のクエリ以降に変更されたデータのみを受信できます (差分更新)。クライアントが初期リクエストでキャッシュのベースハイドレートを実行し、別のリクエストでの増分更新を実行できるようにすることで、その計算をクライアントアプリケーションからバックエンドに移動できます。これは、頻繁にオンライン状態とオフラインの状態を切り替えるクライアントアプリケーションにとって効率が大きく向上します。

Delta Sync を実装するため、Sync クエリはバージョン管理されたデータソースで Sync オペレーションを使用します。ミュー AWS AppSync テーションがバージョニングされたデータソース内の項目を変更すると、その変更の記録も Delta テーブルに保存されます。他のバージョニングされたデータソースには異なる Delta テーブル (タイプごとに 1 つ、ドメインエリアごとに 1 つなど) を使用するか、 に 1 つの Delta テーブルを使用するかを選択できますAPI。プライマリキーの衝突を避けるためAPIs、複数の に 1 つの Delta テーブルを使用することは AWS AppSync 推奨されません。

さらに、Delta Sync クライアントはサブスクリプションを引数として受け取ることもでき、オフラインからオンラインへの移行間でサブスクリプションの再接続と書き込みを調整します。そのために、Delta Sync はサブスクリプション (さまざまなネットワークエラーシナリオでの、エクスポネンシャルバックオフや、ジッターを伴う再試行など) を自動的に再開し、イベントをキューに保存します。その後、該当する差分クエリまたは基本クエリを実行してから、キュー内のイベントをマージし、最後に通常どおりにサブスクリプションを処理します。

Amplify を含むクライアント設定オプションのドキュメント DataStoreは、Amplify Framework ウェブサイト で入手できます。このドキュメントは、最適なデータアクセスのために Delta Sync クライアントと連携するように、バージョン管理された DynamoDB データソースと Sync オペレーションをセットアップする方法について概説しています。

ワンクリックでのセットアップ

すべてのリゾルバーと必要な AWS リソースを設定した AWS AppSync で GraphQL エンドポイントを自動的にセットアップするには、次の AWS CloudFormation テンプレートを使用します。

Blue button labeled "Launch Stack" with an arrow icon indicating an action to start.

このスタックはお客様のアカウントに以下のリソースを作成します。

  • 2 つの DynamoDB テーブル (基本と差分)

  • API キー付き 1 AWS AppSync API

  • 1 DynamoDB テーブルのポリシーを持つIAMロール

2 つのテーブルは、クライアントがオフラインのときに取得できなかったイベントのジャーナルとして機能する 2 番目のテーブルに、同期クエリを分割するために使用されます。デルタテーブルでクエリを効率的に維持するために、Amazon DynamoDB TTLs は必要に応じてイベントを自動的にグルーミングするために使用されます。TTL 時間はデータソースのニーズに応じて設定できます (1 時間、1 日など)。

Schema

Delta Sync を実証するために、サンプルアプリケーションは DynamoDB の Base テーブルと Delta テーブルでバックアップされた Posts スキーマを作成します。 AWS AppSync は両方のテーブルにミューテーションを自動的に書き込みます。同期クエリは必要に応じて、ベーステーブルまたは差分テーブルからレコードをプルします。また、1 つのサブスクリプションは、クライアントが再接続ロジックでこのテーブルをどのように活用できるかを定義します。

input CreatePostInput { author: String! title: String! content: String! url: String ups: Int downs: Int _version: Int } interface Connection { nextToken: String startedAt: AWSTimestamp! } type Mutation { createPost(input: CreatePostInput!): Post updatePost(input: UpdatePostInput!): Post deletePost(input: DeletePostInput!): Post } type Post { id: ID! author: String! title: String! content: String! url: AWSURL ups: Int downs: Int _version: Int _deleted: Boolean _lastChangedAt: AWSTimestamp! } type PostConnection implements Connection { items: [Post!]! nextToken: String startedAt: AWSTimestamp! } type Query { getPost(id: ID!): Post syncPosts(limit: Int, nextToken: String, lastSync: AWSTimestamp): PostConnection! } type Subscription { onCreatePost: Post @aws_subscribe(mutations: ["createPost"]) onUpdatePost: Post @aws_subscribe(mutations: ["updatePost"]) onDeletePost: Post @aws_subscribe(mutations: ["deletePost"]) } input DeletePostInput { id: ID! _version: Int! } input UpdatePostInput { id: ID! author: String title: String content: String url: String ups: Int downs: Int _version: Int! } schema { query: Query mutation: Mutation subscription: Subscription }

GraphQL スキーマは標準的なものですが、先に進む前に注意することがいくつかあります。最初に、すべてのミューテーションは自動的にベーステーブルに書き込み、次に差分テーブルに書き込みます。基本テーブルは、実際の一元的なソースであり、一方、差分テーブルはジャーナルです。を渡さない場合lastSync: AWSTimestampsyncPostsクエリは Base テーブルに対して実行され、キャッシュをハイドレートし、クライアントが Delta テーブルで設定したTTL時間よりも長くオフラインになっているエッジケースのグローバルキャッチアッププロセスとして定期的に実行されます。lastSync: AWSTimestamp を渡す場合、syncPosts クエリは差分テーブルに対して実行されます。クライアントはこのクエリを使用して、最後のオフライン以降に変更されたイベントを取得します。Amplify クライアントは自動的に lastSync: AWSTimestamp 値を渡し、適切にディスクに保持します。

Post_deleted フィールドはDELETEオペレーションに使用されます。クライアントがオフラインになり、レコードが基本テーブルから削除されると、この属性は、同期中のクライアントにローカルキャッシュから項目をエビクションするように通知します。クライアントが長期間オフラインであり、クライアントが Delta Sync クエリでこの値を取得する前に項目が削除された場合は、基本クエリのグローバルキャッチアップイベント (クライアントで設定可能) が実行され、キャッシュからその項目が削除されます。このフィールドがオプションとしてマークされているのは、同期クエリの実行時に、削除された項目がある場合にのみ値を返すためです。

ミューテーション

すべてのミューテーションについて、 は Base テーブルに標準Create/Update/Deleteオペレーション AWS AppSync を行い、Delta テーブルに変更を自動的に記録します。データソースの DeltaSyncTableTTL 値を変更することで、レコードを保持する時間を短縮または延長できます。データの速度が速い組織では、この時間を短縮するのが妥当な場合があります。あるいは、クライアントが長期間オフラインになっている場合は、この時間を延長するのが賢明でしょう。

同期クエリ

基本クエリは、lastSync 値が指定されていない DynamoDB の同期オペレーションです。多くの組織にとって、基本クエリで十分です。基本クエリは起動時に実行され、以降は定期的に実行されるためです。

差分クエリは、lastSync 値が指定された DynamoDB の同期オペレーションです。差分クエリは、クライアントがオフライン状態からオンライン状態に戻るたびに実行されます (基本クエリが定期的にトリガーされていない場合)。クライアントは、データを同期するクエリを最後に正常に実行した時刻を自動的に追跡します。

差分クエリが実行されると、クエリのリゾルバーは ds_pkds_sk を使用して、クライアントが前回同期を実行してから変更されたレコードに対してのみクエリを実行します。クライアントは該当する GraphQL レスポンスを保存します。

同期クエリの実行の詳細については、同期オペレーションのドキュメントを参照してください。

まず、項目を作成するために createPost ミューテーションを呼び出すことから始めましょう。

mutation create { createPost(input: {author: "Nadia", title: "My First Post", content: "Hello World"}) { id author title content _version _lastChangedAt _deleted } }

このミューテーションの戻り値は次のようになります。

{ "data": { "createPost": { "id": "81d36bbb-1579-4efe-92b8-2e3f679f628b", "author": "Nadia", "title": "My First Post", "content": "Hello World", "_version": 1, "_lastChangedAt": 1574469356331, "_deleted": null } } }

ベーステーブルの内容を調べると、次のようなレコードがあります。

{ "_lastChangedAt": { "N": "1574469356331" }, "_version": { "N": "1" }, "author": { "S": "Nadia" }, "content": { "S": "Hello World" }, "id": { "S": "81d36bbb-1579-4efe-92b8-2e3f679f628b" }, "title": { "S": "My First Post" } }

差分テーブルの内容を調べると、次のようなレコードがあります。

{ "_lastChangedAt": { "N": "1574469356331" }, "_ttl": { "N": "1574472956" }, "_version": { "N": "1" }, "author": { "S": "Nadia" }, "content": { "S": "Hello World" }, "ds_pk": { "S": "AppSync-delta-sync-post:2019-11-23" }, "ds_sk": { "S": "00:35:56.331:81d36bbb-1579-4efe-92b8-2e3f679f628b:1" }, "id": { "S": "81d36bbb-1579-4efe-92b8-2e3f679f628b" }, "title": { "S": "My First Post" } }

これで、クライアントが syncPosts クエリなどを実行してローカルデータストアをハイドレートするために実行する基本クエリをシミュレーションすることができます。

query baseQuery { syncPosts(limit: 100, lastSync: null, nextToken: null) { items { id author title content _version _lastChangedAt } startedAt nextToken } }

この基本クエリの戻り値は次のようになります。

{ "data": { "syncPosts": { "items": [ { "id": "81d36bbb-1579-4efe-92b8-2e3f679f628b", "author": "Nadia", "title": "My First Post", "content": "Hello World", "_version": 1, "_lastChangedAt": 1574469356331 } ], "startedAt": 1574469602238, "nextToken": null } } }

差分クエリをシミュレーションするために後で startedAt 値を保存しますが、まずはテーブルを変更する必要があります。updatePost ミューテーションを使って既存の投稿を変更しましょう。

mutation updatePost { updatePost(input: {id: "81d36bbb-1579-4efe-92b8-2e3f679f628b", _version: 1, title: "Actually this is my Second Post"}) { id author title content _version _lastChangedAt _deleted } }

このミューテーションの戻り値は次のようになります。

{ "data": { "updatePost": { "id": "81d36bbb-1579-4efe-92b8-2e3f679f628b", "author": "Nadia", "title": "Actually this is my Second Post", "content": "Hello World", "_version": 2, "_lastChangedAt": 1574469851417, "_deleted": null } } }

ここでベーステーブルの内容を調べると、更新された項目が表示されます。

{ "_lastChangedAt": { "N": "1574469851417" }, "_version": { "N": "2" }, "author": { "S": "Nadia" }, "content": { "S": "Hello World" }, "id": { "S": "81d36bbb-1579-4efe-92b8-2e3f679f628b" }, "title": { "S": "Actually this is my Second Post" } }

ここで差分テーブルの内容を調べると、次の 2 つのレコードがあります。

  1. 項目が作成されたときのレコード

  2. 項目が更新されたときのレコード

新しい項目は次のようになります。

{ "_lastChangedAt": { "N": "1574469851417" }, "_ttl": { "N": "1574473451" }, "_version": { "N": "2" }, "author": { "S": "Nadia" }, "content": { "S": "Hello World" }, "ds_pk": { "S": "AppSync-delta-sync-post:2019-11-23" }, "ds_sk": { "S": "00:44:11.417:81d36bbb-1579-4efe-92b8-2e3f679f628b:2" }, "id": { "S": "81d36bbb-1579-4efe-92b8-2e3f679f628b" }, "title": { "S": "Actually this is my Second Post" } }

差分クエリをシミュレートして、クライアントがオフラインのときに発生した変更を取得できるようになりました。リクエストを行うために、基本クエリから返された値 startedAt を使用します。

query delta { syncPosts(limit: 100, lastSync: 1574469602238, nextToken: null) { items { id author title content _version } startedAt nextToken } }

この差分クエリの戻り値は次のようになります。

{ "data": { "syncPosts": { "items": [ { "id": "81d36bbb-1579-4efe-92b8-2e3f679f628b", "author": "Nadia", "title": "Actually this is my Second Post", "content": "Hello World", "_version": 2 } ], "startedAt": 1574470400808, "nextToken": null } } }