10.2. サーバーでの競合の検出
競合を検出するための一般的なフローには、次の手順が含まれます。
- A Mutation Occurs - クライアントが GraphQL ミューテーションを使用してサーバー上のオブジェクトを変更または削除しようとします
- Read the Object - サーバーは、クライアントが変更しようとしている現在のオブジェクトをデータソースから読み取ります
- Conflict Detection - サーバーは、現在のオブジェクトをクライアントから送信されたデータと比較して、競合があるかどうかを確認します。開発者は、比較の実行方法を選択します。
aerogear/voyager-conflicts モジュールは、ストレージテクノロジーに関係なく、開発者が Conflict Detection 手順を実行するのに役立ちますが、データのフェッチと保存は開発者の責任です。
このリリースは、次の実装をサポートします。
-
VersionedObjectState- オブジェクトで提供されるバージョンフィールドに依存します (conflictHandler をインポートするときにデフォルトでバージョンフィールドが使用されます)。詳細は、以下を参照してください: 「バージョンベースの競合検出の実装」 -
HashObjectState- オブジェクト全体から計算されたハッシュに依存します。詳細は、以下を参照してください: 「ハッシュベースの競合検出の実装」
これらの実装は ObjectState インターフェイスに基づいており、そのインターフェイスを拡張して、競合検出用のカスタム実装を提供できます。
前提条件
- リゾルバーを備えた GraphQL サーバー。
- データの競合を引き起こす可能性のあるデータベースまたはその他の形式のデータストレージ。Red Hat は、データをセキュアな場所に保存することをお勧めします。データベースを使用する場合、そのデータベースを管理、保守、およびバックアップするのはユーザーの責任です。他の形式のデータストレージを使用する場合は、データをバックアップする責任があります。
10.2.1. バージョンベースの競合検出の実装 リンクのコピーリンクがクリップボードにコピーされました!
バージョンベースの競合解決は、競合の検出と解決に推奨される最もシンプルなアプローチです。中心的な考え方は、すべてのオブジェクトに整数値の version プロパティーがあるということです。クライアントから送信されたバージョン番号がサーバーに保存されているバージョンと一致しない場合、conflict が発生します。これは、別のクライアントがすでにオブジェクトを更新していることを意味します。
手順
@aerogear/voyager-conflicts パッケージをインポートします。
const { conflictHandler } = require('@aerogear/voyager-conflicts')const { conflictHandler } = require('@aerogear/voyager-conflicts')Copy to Clipboard Copied! Toggle word wrap Toggle overflow 競合解決をサポートするバージョンフィールドを GraphQL タイプに追加します。バージョンもデータストレージに保存する必要があります。
type Task { title: String version: Int }type Task { title: String version: Int }Copy to Clipboard Copied! Toggle word wrap Toggle overflow ミューテーションの例を追加します。
type Mutation { updateTask(title: String!, version: Int!): Task }type Mutation { updateTask(title: String!, version: Int!): Task }Copy to Clipboard Copied! Toggle word wrap Toggle overflow リゾルバーを実装します。すべての競合は、次のような事前定義された一連の手順を使用して処理できます。
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
上記の例では、throw ステートメントにより、クライアントが競合クライアント側を解決するために必要なすべてのデータを確実に受信します。このデータの詳細は、Structure of the Conflict Error を参照してください。
競合はクライアントで解決されるため、データを保持する必要はありません。ただし、競合がない場合は、クライアントから送信されたデータを保持する必要があります。クライアント側の競合の解決の詳細は、Resolving Conflicts on the Client を参照してください。