sync/set 型 API のリスト外削除は全要素成功時のみ実行する
データベース
API設計
判断
運用
「渡したリストを最終状態とする」sync / set 型の一括 API に、部分成功(要素独立でエラーを返す)を組み合わせると、1要素の入力ミスでリスト外の既存レコードが不可逆に消える。
失敗シナリオ
更新するつもりで id を参照した要素が型ミスなどでデコード失敗すると、その id は「保持対象」の集合に入らない。他の要素が成功していれば削除フェーズが走り、参照したはずのレコードがリスト外として消える。ユーザーから見れば「更新しようとしたものが消えた」になる。
契約
- 削除フェーズのゲートを failed_count == 0(全要素成功) にする。「成功が1件以上あれば削除する」は fail-open。1件でも失敗したら削除はスキップし、削除済み id は空で返す。
- 削除は単一トランザクションにする。対象 id をロック付きでスナップショットし、保持集合との差集合を1回の DELETE で消す。途中失敗は全ロールバック。
- 入力のデコードは要素独立にする。配列を丸ごと1つの構造体へデコードすると、1件の不正な日時などで全体が 400 になり、部分成功の意味が消える。要素は生 JSON として受けて個別にデコードする。
- 作成/更新の分岐は「id キーが存在するか」で決める。値0や文字列 id を「未指定=作成」に化けさせると、作成扱いになった要素が削除フェーズまで通ってしまう。
- 空配列は拒否する(全件削除の抜け道になる)。
表明の場所
この「全要素成功時のみ削除」という性質は、呼び出し側から見て挙動が非自明なので、API / ツールの説明文自体に書く。返り値の形だけでは読み取れない。