用二進位 artifact 當 API 的傳輸格式
主張:當資料量大到 JSON 傳不動時,可以讓後端直接產出一個二進位檔(例如
.sqlite),前端下載後即用——中間零 transform。這比「把 JSON 切小塊分頁傳」更徹底,因為它同時解掉了傳輸、記憶體與查詢三個問題。
好處
- 傳輸:gzip 後體積約十分之一,繞過 body-size 限制
- 記憶體:前端不用把每列展開成物件(見 JS 物件比原始資料胖好幾倍)
- 查詢:檔案本身就是可查詢的資料結構,排序/搜尋/分頁全下推
- 對稱:前端 export 出來的 bytes 就是一份合法的同格式檔案,可以直接送回後端用原生函式庫打開
代價:單位從「一列」變成「一份」
協定極簡(沒有 patch 語意、沒有版本衝突),但沒有任何增量路徑。改三格與改三萬格的送出成本一樣:整份 export(記憶體峰值)、整份壓縮、整份上傳、後端整份重驗。失敗重試也是整份重來。
實務上的折衷是兩層:編輯當下走原本的細粒度 JSON endpoint 做即時驗證,整份 artifact 只在最終提交時往返一次 → 前端的即時驗證是 UX,後端重驗才是 gate。
必要的防護
artifact 是使用者可以修改的不可信輸入,收下時至少要做:完整性檢查(PRAGMA integrity_check 之類)、表/索引白名單、明確列出欄位的 SELECT(不要 SELECT *)、逐列重跑長度上限——不要因為是自己 writer 產的就信任它。另外要在檔案裡寫入 schema 版本並在讀取端比對,否則前後端版本不一致時會以奇怪的方式壞掉。
失敗回饋也可以用同一招的縮小版:只回一份只含錯誤表的 artifact,讓前端合併回原本那份就地修正,不必重跑整個流程 → 失敗時只回錯誤集合,讓使用者就地修正。