Name:
interface
Value:
Amplify has re-imagined the way frontend developers build fullstack applications. Develop and deploy without the hassle.

Page updated May 2, 2026

Maintenance ModeYou are viewing Amplify Gen 1 documentation. Amplify Gen 1 has entered maintenance mode and will reach end of life on May 1, 2027. New project should use Amplify Gen 2. For existing Gen 1 projects, a migration guide and tooling are available to help you upgrade. Switch to the latest Gen 2 docs →

コンフリクト解決の無効化

フロントエンド移行を最初に完了してください。 このページはこのガイドの最終的なバックエンドステップです。これらの指示に従う前に、このガイドの前のページを使用して、すべてのフロントエンドクライアントを DataStore から移行してください。DataStore を使用しているクライアントがある状態でコンフリクト解決を無効化すると、そのクライアントは直ちに破損します。

このページでは、AppSync API のコンフリクト解決を無効化するために必要なバックエンド変更を説明します。すべてのフロントエンドクライアントが DataStore から移行された後、コンフリクト解決を無効化するとシンクインフラストラクチャ(バージョン追跡、論理削除、差分シンク)が削除され、より簡潔で標準的な GraphQL API が実現します。

問題点

DataStore が有効な場合、Amplify は AppSync をコンフリクト解決で設定します。これにより、移行に影響を与える 3 つの動作が発生します:

  1. 論理削除。 DataStore を通じて削除されたアイテムは DynamoDB から削除されません。代わりに、DataStore はアイテムに _deleted: true を設定します。アイテムはテーブルに無期限に残るか、DynamoDB TTL が期限切れになるまで残ります。

  2. メタデータフィールド。 コンフリクト解決は、生成された GraphQL スキーマの各モデルに _deleted_version_lastChangedAt フィールドを追加します。DataStore はシンクプロトコル用にこれらのフィールドを内部で使用します。

  3. スキーマの結合。 コンフリクト解決を無効化した場合、Amplify は GraphQL スキーマから _deleted_version_lastChangedAt を削除します。ただし、DynamoDB テーブルには引き続き _deleted: true の論理削除されたアイテムを含む、これらの属性を持つアイテムが含まれます。

DataStore から標準 GraphQL クライアント(Apollo Client など)にフロントエンドを切り替える際に _deleted フィールドに対処しない場合、アプリは隠すべき論理削除されたアイテムを表示します。

移行ステップの概要

ステップアクション目的
1コンフリクト解決を無効化AppSync が _version と論理削除を管理するのを停止
2スキーマにメタデータフィールドを再追加クライアントが _deleted_version_lastChangedAt を使用できるように維持
3変更をプッシュ更新された設定をバックエンドに適用
4クリーンアップ(オプション)DynamoDB から論理削除されたアイテムをパージし、クライアント側の _deleted フィルタリングを削除

ステップ 1: コンフリクト解決を無効化

Amplify CLI を実行して GraphQL API のコンフリクト解決を無効化します:

amplify update api

プロンプトが表示されたら:

  1. GraphQL を選択します
  2. コンフリクト解決設定が表示されるまでオプションを実行します
  3. Disable DataStore for entire API(または CLI バージョンに応じて Disable conflict resolution)を選択します

まだ amplify push を実行しないでください。 ステップ 2 を最初に完了する必要があります。この時点でプッシュすると、スキーマから _deleted_version_lastChangedAt フィールドが削除されますが、DynamoDB の既存データには引き続きこれらの属性が含まれます。AppSync はスキーマに存在しなくなったフィールドをクエリまたはミューテーションで返すと ValidationError を返します。

ステップ 2: GraphQL スキーマにメタデータフィールドを再追加

コンフリクト解決を無効化した後、Amplify はスキーマから _deleted_version_lastChangedAt を削除します。ただし、DynamoDB テーブルはすべてのアイテムにこれらの属性を引き続き含んでいます。GraphQL スキーマファイル(amplify/backend/api/<apiname>/schema.graphql)の各モデルに 3 つのフィールドすべてを再追加します:

type Todo @model @auth(rules: [{ allow: owner }]) {
id: ID!
name: String!
description: String
_deleted: Boolean
_version: Int
_lastChangedAt: AWSTimestamp
}
type Post @model @auth(rules: [{ allow: owner }]) {
id: ID!
title: String!
content: String
status: String
_deleted: Boolean
_version: Int
_lastChangedAt: AWSTimestamp
}

以前 DataStore で管理されていたすべてのモデル_deleted: Boolean_version: Int_lastChangedAt: AWSTimestamp を追加します。

一貫性のために 3 つのフィールドすべてを再追加します。 コンフリクト解決を無効化した後、AppSync はこれらのフィールドを管理しなくなりますが、DynamoDB テーブルはすべてのアイテムに _deleted_version_lastChangedAt を引き続き含んでいます。それらを再追加すると、GraphQL スキーマが DynamoDB のデータと整合し、移行期間中にクライアントがこれらの属性をクエリまたはフィルタリングできるようになります。

これが機能する理由

これらのフィールドをスキーマの通常フィールドとして追加すると:

  • AppSync は各フィールドを既存の DynamoDB 属性にマップします。 DynamoDB はスキーマレスなので、_deleted_version_lastChangedAt はすべてのアイテムに既に存在しています。AppSync の自動生成リゾルバーはこれらの属性を直接読み書きします。
  • フィールドは生成されたフィルターおよび入力型に表示されます。 これらをモデルに追加すると、ModelTodoFilterInputModelPostFilterInput などの生成型で利用可能になります。クライアントは _deleted のサーバー側フィルタリングを使用したり、移行中に必要に応じて _version または _lastChangedAt を読み取ることができます。
  • 下位互換性があります。 既存のアイテムはこれらの属性の値を保持します。コンフリクト解決を無効化した後に作成された新規アイテムは、明示的に設定されない限り null になります。

これらのフィールドは AppSync で管理されなくなります。 コンフリクト解決を無効化した後、_version は自動インクリメントされず、_lastChangedAt は自動更新されません。これらは通常フィールドになります。削除はハード削除になり、_deleted は自動的に設定されません。

ステップ 3: 変更をプッシュ

更新された設定をバックエンドに適用します:

amplify push

これによって以下が行われます:

  • AppSync でコンフリクト解決を無効化(シンクテーブル設定と差分シンクリゾルバーを削除)
  • _deleted_version_lastChangedAt を GraphQL スキーマの通常フィールドとして維持
  • 各フィールドをすべてのアイテムの既存 DynamoDB 属性にマップ(データ移行は不要)

プッシュ後、AppSync は _version を管理しなくなり、ソフト削除を実行しません。GraphQL API を通じた新規削除は DynamoDB からハード削除します(コンフリクト解決なしのデフォルト動作)。

ステップ 4(オプション): 論理削除されたアイテムをクリーンアップ

すべてのクライアントが移行され、すべてが正しく機能していることを確認した後、DynamoDB から論理削除されたアイテムをパージし、コード内のクライアント側 _deleted フィルタリングを削除できます。

4a. DynamoDB から論理削除されたアイテムをハード削除

各 DynamoDB テーブルをスキャンし、_deletedtrue であるすべてのアイテムを削除するスクリプトを書きます:

import {
DynamoDBClient,
ScanCommand,
DeleteItemCommand,
} from '@aws-sdk/client-dynamodb';
const client = new DynamoDBClient({ region: 'us-east-1' });
async function purgeSoftDeletedItems(tableName: string) {
let lastEvaluatedKey: Record<string, any> | undefined;
do {
const scanResult = await client.send(
new ScanCommand({
TableName: tableName,
FilterExpression: '#d = :true',
ExpressionAttributeNames: { '#d': '_deleted' },
ExpressionAttributeValues: { ':true': { BOOL: true } },
ExclusiveStartKey: lastEvaluatedKey,
})
);
for (const item of scanResult.Items ?? []) {
await client.send(
new DeleteItemCommand({
TableName: tableName,
Key: { id: item.id },
})
);
console.log(`Deleted item ${item.id.S} from ${tableName}`);
}
lastEvaluatedKey = scanResult.LastEvaluatedKey;
} while (lastEvaluatedKey);
}
// 各テーブルに対して実行
await purgeSoftDeletedItems('Todo-<apiId>-<env>');
await purgeSoftDeletedItems('Post-<apiId>-<env>');

このスクリプトをまず開発環境でテストしてください。 _deletedtrue であるアイテムのみを削除することを確認します。テーブルが複合キー(ソートキー)を使用する場合、DeleteItemCommandKey オブジェクトを適切に更新します。

4b. クライアントコードを更新

論理削除されたアイテムをパージした後、コードからクライアント側の _deleted フィルタリングを削除します。フロントエンド移行中に、リストクエリ結果に .filter(item => !item._deleted) を追加しました。DynamoDB からすべての論理削除されたアイテムが削除されたら、これは不要になります。

// クリーンアップ前: 論理削除されたアイテムをフィルタリング
const posts = data.listPosts.items.filter((post) => !post._deleted);
// クリーンアップ後: フィルターは不要
const posts = data.listPosts.items;

重要な考慮事項

論理削除されたアイテムを最初にパージしない理由

すべてのクライアントが同時に DataStore を停止することは保証できません。ユーザーはアプリのキャッシュされたバージョンを実行している可能性があります。また、デプロイメントが段階的にロールアウトされる可能性があります。一部のクライアントがまだスキーマで _deleted を期待している状態でコンフリクト解決を無効化すると、ValidationError 例外が発生します。

このガイドのアプローチは下位互換性があります。DataStore クライアント(移行中)と標準 GraphQL クライアントが共存できます。これは _deleted が通常フィールドとしてスキーマに残るためです。

DynamoDB TTL と論理削除されたアイテム

DataStore が有効な場合、Amplify は DynamoDB の _ttl 属性に TTL を設定することがあります。TTL を持つ論理削除されたアイテムは、TTL の期限切れ後に DynamoDB によって自動的にハード削除されます。

コンフリクト解決を無効化した後:

  • DynamoDB テーブルの TTL 設定は引き続きアクティブ(テーブルレベル設定であり、AppSync で管理されないため)
  • _ttl 値を持つ既存の論理削除されたアイテムは引き続き自動的に削除されます
  • 新規削除はハード削除になります(_ttl は設定されません)

AWS コンソール(テーブル → テーブル → 追加設定 → Time to Live)で DynamoDB テーブルの TTL 設定を確認します。

メタデータフィールドは自動管理されなくなります

コンフリクト解決を無効化した後、AppSync はミューテーション時に _version を自動インクリメントしたり、_lastChangedAt を自動更新しなくなります。フィールドは DynamoDB の最後の値を保持でき、クライアントが読み取ることができますが、アプリケーションコードが明示的に設定しない限り更新されません。クリーンアップステップ(ステップ 4)中に、論理削除されたアイテムをパージし、クライアント側の _deleted フィルタリングを削除できます。

移行後の監視

移行を完了した後、アプリケーションで以下を監視します:

  • AppSync CloudWatch ログの ValidationError これはクライアントがスキーマに存在しなくなったフィールドで問い合わせまたはミューテーションを送信していることを示します。
  • リストクエリの予期しないアイテム。 論理削除されたアイテムが表示される場合は、すべてのリストクエリ結果がクライアント側で .filter(item => !item._deleted) でフィルタリングされていることを確認します。
  • DynamoDB の ConditionalCheckFailedException コンフリクト解決を無効化した後、_version チェックが強制されなくなるため、これは発生しなくなります。