ページング前提の一括操作で全件選択は includedIds と searchCondition+excludedIds の二系統で受ける
フロントエンド
設計判断
API設計
判断
原則
ページング/フィルタ前提の一覧で「全件選択して一括操作」を実現するとき、対象を ID の明示列挙だけで受けると、検索結果が数万件あるケースでクライアントが全 ID を列挙できず破綻する。Gmail の「N 件すべてを選択」と同じ枠組みで、選択を2系統に分けて受けるとよい。
契約(判断基準)
- 個別選択: 明示 ID 群(includedIds)。
- 全件選択: 検索条件(searchCondition)。条件にマッチする全件が対象。
- 全件選択して一部解除: 検索条件 + 除外 ID 群(excludedIds)。条件マッチ全件から除外分を引く。
- includedIds と searchCondition は排他(どちらか一方)。excludedIds は searchCondition 併用時のみ有効。バリデーションで強制する。
サーバ側の materialize
- 検索条件はサーバが「権限考慮の検索」で全該当 ID へ展開(materialize)し、ジョブ作成時に ID スナップショットとして保存する。これにより後段(chunk 処理・中断再開)は固定 ID リストをそのまま扱え、選択モードの差を意識しなくて済む。
- 件数上限を設け、超過時・対象0件時はエラーにする(無制限 materialize は OOM とコスト爆発の元)。
- materialize を作成 API(同期)でやるとヒット数次第で POST が重くなる。上限で有界化するか、総件数だけ先に確定して materialize を非同期ワーカー側へ寄せる選択肢がある。トレードオフを明示して決める。
フロント側
- 全件選択はフラグ + 除外 Set で持ち、選択件数は「検索ヒット総数 − 除外数」で表示する(全 ID を保持しない)。総数は一覧 API のページングメタから得る。
- 表示件数は瞬間の概算で、materialize 時点のデータ変化でズレ得ることを許容するか、件数確認 API で厳密化するかを決める。
注意(関連する落とし穴)
- 全 ID 取得に汎用検索/一覧をそのまま流用すると、デフォルト件数上限やレコード本文の重い転送を一緒に背負う。ID だけ要る経路は本文を載せない軽い索引取得にするのが望ましい。
- 明示 ID 群を body で受ける経路は、件数次第で body parser / WAF / payload / キューのサイズ制限に当たる。スキーマ上限だけでなく経路全体の制限を揃える。