ADR-0001 展示用 API 不接資料庫
已採納 · 2026-09-09
進件 API 要模擬案件的建立與狀態流轉,直覺上這需要一個資料庫。這是一個示範服務, 但它的用途是讓沒見過我程式碼的人相信我能建置並維運系統,所以「看起來像玩具」是要避免的。
同時它有三個和產品系統很不一樣的約束:
- 沒有真實資料需要保存。 任何人建立的案件都是測試資料,遺失沒有代價。
- 營運成本由我自己負擔,而且我正在轉職。 一個閒置時仍在計費的受管資料庫, 對一個每週可能只有幾十次請求的展示服務不成比例。
- 它是公開端點。 上線幾小時內就會被掃描,這不是假設。
不接資料庫。 資料放在行程內的 ConcurrentDictionary,啟動時灌入種子案件,
每小時重置回種子狀態,使用者建立的案件上限 200 筆。
成本。 沒有資料庫就沒有資料庫帳單。Container Apps 可以 scale-to-zero, 閒置時整個服務的成本趨近於零。
攻擊面。 這是主要理由,不是附帶好處。沒有資料庫就消掉一整類問題: SQL 注入、連線字串外洩、備份的存放與權限、資料庫版本的修補、 以及最現實的一項——公開沙箱被灌入不當內容後,我得負責清理並且可能得對外說明。
可預期性。 每小時重置意味著任何人看到的都是同一組乾淨的種子資料。 一個被前人塞滿垃圾的展示 API,比沒有展示 API 更糟。
這個決定不是免費的,以下都是已知且接受的:
- 資料不持久。 重新部署或重置後,使用者建立的案件會消失。這在文件和
/v1/sandbox端點都明講,而不是讓人自己發現。 - 無法水平擴展。 多個執行個體會各有各的記憶體狀態,同一個案件 ID 在不同執行個體 查得到不同結果。目前部署為單一執行個體,這是刻意的。真的需要擴展時,這個決定就必須推翻。
- 少了一塊可展示的技能。 資料庫存取、遷移、查詢最佳化是後端工作的核心, 這個 API 完全沒有展示到。這一點由我的實際經歷補上,而不是由這個示範專案。
考慮過的替代方案
Section titled “考慮過的替代方案”SQLite 檔案。 幾乎沒有營運成本,也能展示真實的資料存取層。 但容器是無狀態的,檔案在重新部署時就沒了——那和記憶體儲存的持久性其實一樣, 卻多帶了一整套 ORM 與遷移機制。付出複雜度卻沒換到持久性。
受管的 PostgreSQL(Neon、Supabase 之類的免費方案)。 資料真的會留下來, 也展示得到完整的資料層。但它把上面三個約束全部反過來:多一份要顧的服務、 免費方案有閒置暫停與額度限制、而且沙箱一旦有持久儲存,清理垃圾資料就變成我的長期責任。
未來若要推翻:ApplicationStore 是唯一碰資料的地方,介面只有 All、Find、
Add、Replace、Reset 五個方法。換成資料庫實作時,BatchRunner 與端點都不需要改。