3.1 KiB
ADR-036: FastAPI Strangler Migration,不作為前端 V3 前置條件
Status: Accepted Date: 2026-05-12
Context
前端 V3 視覺包已進入落地評估,同時出現「既然前端要一次到位,後端也應同步從 Flask 改為 FastAPI」的建議。
現有系統的重資產集中在 Python:爬蟲、AI 學習鏈、Telegram bot、APScheduler、SQLAlchemy models、pgvector、AutoHeal 與多個 service 模組。FastAPI 若被定位為 HTTP layer 轉換,理論上可沿用大部分 Python 業務邏輯;但目前 app.py、routes/ 與 Jinja 頁面仍承接大量 HTTP glue、template context、CSRF/session、錯誤處理與部分業務邏輯。
同時,前端 V3 包內部分頁面仍有正式資料接線風險:若只為了視覺更新直接替換,就可能移除現有 PChome 比價、AI 挑品、歷史價格、AI 觀測台等真實功能,違反 CONSTITUTION 第 14.1 條。
Decision
FastAPI 是可接受的中期目標,但不得作為前端 V3 落地的前置條件,也不得與前端視覺更新綁成同一個大爆炸工程。
採用以下順序:
- 前端 V3 先在現有 Flask runtime 內落地,僅替換已確認接上真實資料、既有 route/API 與行為不退化的頁面。
- 對於會移除現有功能的 V3 prototype 頁,先拒絕替換,保留現行正式頁。
- 後端重構優先做 HTTP-agnostic service extraction:把 route 內資料組裝、查詢、匯出、狀態診斷逐步搬到
services/,讓 Flask route 變薄。 - FastAPI 僅能以 strangler pattern 漸進引入:新 API 或已抽乾的 API 可掛在新 app,經 OpenAPI contract、測試與 Nginx path split 驗證後再切流。
- 不採用 Node 重寫後端。Next.js 前端若需要型別,未來由 OpenAPI 產生 client/types,不以「前後端同語言」作為重寫理由。
Alternatives Considered
A. 前端 V3 與 FastAPI Phase 1 同時執行
拒絕。這會同時改動 template/rendering、API boundary、auth/session、CSRF、Nginx、Docker、health check 與 deploy rollback。對目前生產系統而言,風險面過大,也會把原本可獨立驗收的 UI 工作變成跨層遷移。
B. 維持 Flask 永久不動
拒絕作為長期結論。Flask 可繼續承接現有 Jinja/route,但 OpenAPI、型別 client、async API 與新前端資料邊界確實更適合用 FastAPI 承接。問題不是是否能換,而是何時、以什麼切面換。
C. Node/Next API 重寫
拒絕。核心業務與自動化資產都在 Python,改 Node 等同重寫爬蟲、AI、排程、Telegram 與資料層,收益不足以抵銷風險。
Consequences
- 前端 V3 可以立即繼續落地,但每頁必須通過真實資料與行為不退化檢查。
- FastAPI migration 的第一步不是開新框架,而是清 route、補 contract、抽 services。
- 若未來建立
momo-fastapiservice,必須先有:- endpoint inventory 與 owner mapping;
- auth/session/CSRF 或 token strategy;
- OpenAPI contract test;
/health、production smoke、rollback plan;- Nginx path split 只切已驗證 path。
- Flask、Jinja 與
templates/的刪除只能在所有對應頁面完成遷移並通過 smoke 後進行。