メインコンテンツまでスキップ

データの追加

楽観的更新(optimistic updates)による高速で応答性の高いユーザー体験。

なぜ Mutations を使うのか

データベース内で新しいレコードを作成したり、既存のレコードを更新したりする必要があります。Squid Client SDK は、クライアント側で変更を楽観的に適用して UI に即時フィードバックを返し、その後サーバーと非同期に同期する insert と update の操作を提供します。

クイックスタート

Client code
// Insert a new document
await squid.collection<User>('users').doc('user_1').insert({
name: 'Alice',
email: 'alice@example.com',
});

概要

transaction 内で実行されない限り、すべての insert と update は Promise を返し、その mutation がサーバーに適用された時点で resolve します。

insert と update はローカルで楽観的に適用され、クライアントに即座に反映されます。変更内容はその後、整合性がありクリーンなデータ状態を保証するために、サーバーへ非同期に送信されます。

書き込み mutation には insertupdatesetInPath の 3 種類があります。いずれも document reference に対して実行されます。

コアコンセプト

Insert

Insert は新しいドキュメントを作成するために使用します。 コレクションに新しいドキュメントを insert するには、DocumentReference に対して insert メソッドを呼び出し、 新しいドキュメントデータを引数として渡します。

Client code
try {
await squid.collection<User>('users').doc('new_user_id').insert({
name: 'John Doe',
email: 'johndoe@example.com',
});
console.log('User added successfully');
} catch (error) {
console.error(`Failed to add user ${error}`);
}
Tip

バックエンドの security rules により、各 mutation を誰が実行できるかを粒度高く制御できます。これらのルールは MutationContext をパラメータとして受け取り、変更前後のドキュメントの snapshot など、mutation に必要な詳細をすべて含みます。security rules の詳細を読んで、書き方を理解してください。

Insert many

insertMany メソッドは、複数ドキュメントを一度に効率よく insert および/または update するために使用します。次の例では、新しい user ドキュメントの配列を追加します。

Client code
const newDocuments = [
{
id: 'new_user_id1',
data: {
name: 'John Doe',
email: 'johndoe@example.com',
},
},
{
id: 'new_user_id2',
data: {
name: 'Jan Smith',
email: 'jansmith@example.com',
},
},
];

try {
await squid.collection<User>('users').insertMany(newDocuments);
console.log('Users added successfully');
} catch (error) {
console.error(`Failed to add users ${error}`);
}

Update

ドキュメントを update するには、DocumentReference に対して update メソッドを呼び出し、 部分的な更新データを含むオブジェクトを引数として渡します。

Client code
try {
await squid
.collection<User>('users')
.doc('existing_user_id')
.update({ email: 'new_email@example.com' });
console.log('User updated successfully');
} catch (error) {
console.error(`Failed to update user ${error}`);
}

Set in Path

DocumentReference に対して setInPath メソッドを呼び出し、プロパティへの path と新しい値を引数として渡すことで、ドキュメントの特定のプロパティだけを update することもできます。path でネストしたプロパティを指定するには、ドット記法を使用します。

Client code
const userRef = squid.collection<User>('users').doc('existing_user_id');

try {
await userRef.setInPath('address.street', 'Main');
console.log('Updated successfully');
} catch (error) {
console.error(`Failed to update user ${error}`);
}

エラーハンドリング

ErrorCauseSolution
Security rule rejectionmutation が security rules によりブロックされたユーザーがそのコレクションに対する書き込み権限を持つことを確認する
Document already exists一部の connector types で、すでに存在する document ID に対して insert を呼び出している既存ドキュメントには update を使うか、ユニークな ID を使用する
Invalid data shapeinsert するデータがコレクション schema と一致しないデータオブジェクトが期待される schema と型に一致することを確認する
Network errormutation の確認のためにサーバーへ到達できなかった楽観的更新はロールバックされるため、操作をリトライする

ベストプラクティス

  1. 部分的な変更には update() を使用する:ドキュメント全体を再 insert するのではなく、変更されたフィールドのみを送信します。

  2. 深いネストの更新には setInPath() を使用する:ドキュメントの他の部分に触れず、単一のネストフィールドだけを変更します。

    Client code
    // Update only the city without affecting other address fields
    await userRef.setInPath('address.city', 'New York');
  3. バルク操作には insertMany() を使用する:サーバーとの往復回数(round trips)を減らします。

  4. 複数ドキュメントにまたがる atomicity が必要な場合は、関連する mutation を transaction でラップする

  5. mutation のエラーを処理する:クライアント側のバリデーションを通過しても、security rules や schema チェックでサーバーにより変更が拒否される場合があります。