API Migration 上線與剩餘 API 盤點計畫
更新日期:2026-08-03
目標
這份計畫要回答四個問題:
- getlancer legacy 一共有多少支公開 API?
- 多少已存在於
pro360_api_82,而且 production 流量真的已導向新機器? - 還有多少正在被正式環境呼叫、但尚未搬移?
- 哪些 legacy API 長期沒有流量,可以評估不搬?
第一輪 30 天盤點已完成,結果與限制見:
完成後應留下:
evidence/YYYY-MM-DD/
├── production_lb_rules.json # 原始檔不進 git
├── staging_lb_rules.json # 原始檔不進 git
├── legacy_api_inventory.csv
├── new_api_inventory.csv
├── api_gap_inventory.csv
├── production_traffic.csv
├── lb_route_inventory.csv
└── rollout_batches.md判斷模型
Legacy/New 程式盤點 ──確認 endpoint 是否存在、route 是否相容
│
Load Balancer rules ──確認目前實際導向 legacy 或 PHP 8.2 target group
│
Production ALB logs ──確認呼叫量、最後呼叫時間、狀態碼與實際 target group
│
Postman + Web/App ────確認 response contract 與真實使用者流程LB 規則只能說明「符合某條規則後送去哪裡」,不能單獨列出 catch-all 規則底下的所有 API;完整盤點必須同時對照程式 route 與 production access log。
一、匯出 production 與 staging Load Balancer
環境必須分開保存
| 項目 | Production | Staging |
|---|---|---|
| Host | api.pro360.com.tw | api-staging.pro360.com.tw |
| ALB | pro360-api | ALB-PRO360-Staging |
| ALB resource id | app/pro360-api/d3898ad14c394f67 | app/ALB-PRO360-Staging/22d9e3275ff14d23 |
| Legacy target group | pro360-getlancer-target-group | staging-php7 |
| PHP 8.2 target group | ec2-pro360-api-prod-php8 等 | pro360-api-staging-php82 |
| Default action | pro360-getlancer-target-group | TG-PRO360-Staging |
| Access log S3 prefix | s3://pro360-alb-logs/web/ | 待獨立確認 |
不要直接把 staging 的 ARN、rule priority 或 target group 複製到 production。ALB listener rule 依 priority 由小到大比對,精確 endpoint rule 必須排在 catch-all/default rule 之前。
執行文件
實際指令、變數意義、輸出檔案與逐步確認方式獨立放在:
先逐段執行 production,再更換 profile/ALB name 另跑 staging。這些指令不修改 AWS,但會在本機建立或覆蓋 JSON;原始檔可能包含 ARN、內部 IP 與環境資訊,不放進共用 git。
二、列出 getlancer 有、pro360_api 沒有的 API
Legacy inventory
不能只找 controller method。至少盤點:
- CakePHP routes、plugin routes 與 convention route。
- 對外 public controller actions,排除 admin/internal-only method。
.json、REST helper、webhook、callback 與 cron 入口。- umbrella endpoint 依實際
action、filter、type或 routing key 拆開。
每筆標準化為:
HTTP method + normalized path + behavior-changing named parameters動態 id 統一成 {id}、移除純追蹤 query string;會改變行為的 named parameter 不可移除。
New inventory
盤點 pro360_api_82 的:
- Endpoint method。
- Route mapping。
- Origin/File fallback 與實際可到達的 URL。
只有 method、但 production/staging URL 無法 route 到它,也算尚未完成。
狀態分類
| 狀態 | 意義 |
|---|---|
MIGRATED_LIVE | 新程式存在,production LB 已導入且有驗證證據 |
MIGRATED_NOT_LIVE | 新程式存在,但 production 尚未導入 |
LEGACY_ACTIVE_GAP | production 仍有流量,新程式缺少或 route 不相容 |
LEGACY_DORMANT_CANDIDATE | 觀察期零流量,待確認是否可不搬 |
NO_MIGRATION_APPROVED | reviewer/product 已明確同意不搬 |
NEW_METHOD_ROUTE_GAP | new method 已寫,但外部 route 到不了 |
OUT_OF_SCOPE | 非公開 API,例如管理或純內部入口;需註明理由 |
api_gap_inventory.csv 至少要有:
method,path,legacy_source,new_source,current_target_group,
calls_7d,calls_30d,calls_90d,last_seen,status,owner,decision_note三、用 production ALB logs 計算正式呼叫量
應分析「進入分流前」的 production ALB access log,不只看單台 legacy Apache/Nginx log。ALB log 可提供 request URL、target group ARN、matched rule priority、狀態碼與處理時間。
現有 Endpoint/V1/In.php::load_api_logs() / ApiMonitorHelper 可作為 parser 參考,但目前有兩個限制:
- S3 prefix 寫死在特定日期。
- 匯入前會刪除
alb_log2s指定時間範圍資料。
因此不要直接用原方法跑全 production 盤點。先做參數化、唯讀 importer,或以 Athena external table 查 S3 原始 log。
完整權限、建表、查詢、匯出、成本控制與錯誤排查見:
每支 API 要統計
- 7 / 30 / 90 天 business request 數。
OPTIONS數量另列,不混入主要呼叫量。- 最後呼叫時間。
- 2xx / 4xx / 5xx 分布。
- peak requests/min、RPS、p50 / p95 / p99 latency。
- caller:Web、iOS、Android、internal/unknown。
- 實際 target group 與 matched rule priority。
ALB access log 是 best-effort delivery,所以「90 天為 0」只能標為 LEGACY_DORMANT_CANDIDATE,還要檢查:
- 是否有繞過此 ALB 的內網/direct call。
- webhook、callback、cron 或 queue consumer。
- 舊版 App 或季節性功能。
- URL normalization 是否把不同 endpoint 錯誤合併。
參考:ALB access logs。
核心數字
Code gap
= legacy 公開 API 總數
- route 相容的新 API
- 已核准不搬的 API
Active gap
= status = LEGACY_ACTIVE_GAP 的 API 數
Traffic coverage
= 已送到 PHP 8.2 的 production business requests
/ 全部 production business API requests2026-08-03 已完成 Production ALB logs 2026-06-04~2026-08-02 UTC 的 60 天重跑。以下目前狀態取最近完整 30 天,並排除 HEAD 探測與 malformed path:
| 指標 | 結果 |
|---|---|
| 可操作的 GET/POST/DELETE endpoint 組 | 153 |
| 新程式存在,正式已切 | 62;parity 另驗 |
| 指定 API Key 走 PHP 8,其餘走 Legacy(搬移中) | 1 |
| 新程式存在但正式仍走 Legacy | 59 |
| 新程式缺少且正式有流量 | 30 |
| 已走新 target,但 route/method 待確認 | 1 |
| 尚未全部走 PHP 8 | 90 |
| 排除的 HEAD/malformed 組 | 45/1 |
完整口徑與證據見 2026-08-03 Production API 60 天盤點。7/28 的 90 天零流量候選仍保留為歷史 snapshot,未用本次 60 天資料改寫。
90 組尚未全走 PHP 8 的 API 已依 caller、使用流程、side effect 與 rollback 範圍分為 22 批;只先建立 B001 的詳細 QA 文件,其餘批次目前只保留範圍。見 PHP 8 API 搬移批次。
route/method 存在不等於 migration 完成;response、DB write、log、queue、header、cookie 與 side effect 仍要逐支完成 legacy parity 驗證。
四、Postman 結合 Web / App 實際操作
Postman 用來保存可重複的 API contract/regression test;Web/App 實際操作用來證明真實 caller、headers、request body、route 與畫面流程。兩者不能互相取代。
建立可重複測試
- 在 staging 操作真實 Web 或 App。
- Web 從 DevTools Network 選 request,使用 Copy as cURL。
- App 可在已授權的 staging 使用 Charles/Proxyman;若 TLS pinning 無法攔截,改用 App debug log 與 server access log,不繞過 production 安全限制。
- 在 Postman 使用 Import → Raw text 匯入 cURL。
- 把環境相關值改成變數:
{{base_url}}
{{api_key}}
{{session_token}}
{{quote_bid_id}}建立兩個 environment:
pro360-staging:允許經審查的資料異動測試。pro360-production-smoke:只允許已確認安全的 read-only / idempotent smoke test。
API key、session token、password、id_token、Authorization 與 cookie 不可寫進文件、collection 或共用 environment;只放 local value、Postman Vault 或團隊核准的 secret storage。
參考:Postman 匯入 cURL、environment variables。
Collection 結構
每支 API 至少包含:
API name/
├── Happy path
├── Missing or invalid input
├── Owner / non-owner
├── Duplicate / retry
├── Legacy baseline vs new staging
└── Production smoke(安全時才建立)回應測試不能只確認 HTTP 200 或 error = 0,還要驗證 response shape、欄位型別與不應多出的欄位:
pm.test('HTTP 200', () => pm.response.to.have.status(200));
const body = pm.response.json();
pm.test('legacy response shape and types', () => {
pm.expect(body).to.be.an('array');
pm.expect(body[0]).to.have.keys([
'QuoteService',
'QuoteFeedback',
'QuoteBid',
'QuoteFeedbackComment',
'FeedbackAttachment'
]);
pm.expect(body[0].QuoteFeedback.id).to.be.a('string');
});依 endpoint 再驗證 headers、cookie、error shape、排序、空陣列/null 與 legacy 不回傳的欄位。可用 Collection Runner 搭配 CSV/JSON data 測多組 id、sort 與 guard input;production 不跑大量或會寫 DB 的 runner。
參考:Postman test scripts、pm.response reference。
回到真實前端 / App 驗證
每個 caller 平台都要獨立留下證據,不能因 Web 成功就推論 iOS/Android 也成功:
- 操作前 snapshot 相關 DB、queue 與 application log。
- 從 Web/iOS/Android 完成一次真實操作。
- 由 Network/server access log 確認 method、path、request 與 response。
- 用 ALB log/header 確認實際命中新 PHP 8.2 target group。
- 確認 UI 狀態與 response contract。
- 查 DB write、activity、transaction、queue/log、notification 等 side effects。
- reload 或重試一次,確認 duplicate/retry 行為與 legacy 一致。
- 還原 staging 測試資料。
每支 API 維護驗證矩陣:
| API | Postman | Web | iOS | Android | DB | Queue/Log | Prod smoke |
|---|---|---|---|---|---|---|---|
{method} {path} | 待測 | 待測/N/A | 待測/N/A | 待測/N/A | 待測 | 待測 | 待測/N/A |
N/A 必須寫理由,例如該功能只有 Web caller。
五、每批 API 的切換流程
Staging
- 先保存 LB rules、target health 與部署 config snapshot。
- 加入精確 host/path rule,導向 PHP 8.2 staging target group。
- 跑 PHPUnit、legacy baseline、Postman collection 與實際 Web/App flow。
- 比對 response、DB、queue/log、cookie/header、config 與 error path。
- 保存測試 id、時間、response 與 side-effect 證據。
Production
- 確認 target health、deployment config、dashboard 與 rollback action。
- 保存變更前 LB rules。
- 使用精確 endpoint path 切換,不先改 broad catch-all。
- 執行安全 smoke test,並確認請求命中新 target group。
- 監看 30–60 分鐘,再觀察 24 小時的流量、latency、4xx/5xx 與 application log。
- 確認穩定後更新
MIGRATED_LIVE與 production evidence。
Rollback 必須是可立即恢復到原 legacy target group 的已審查 LB action。若使用 weighted target groups,不能假設某一 target group unhealthy 時 ALB 會自動把權重轉給另一組;切換前必須有監控與人工/自動 rollback 設計。
參考:ALB weighted forward actions。
六、何時需要增加新機器
不能用「已搬幾支 API」判斷機器數量,要以 peak load 與單機安全容量計算:
Projected peak RPS
= 目前 PHP 8.2 peak RPS
+ 下一批 endpoint 在相同尖峰時段的 legacy peak RPS
Required capacity
= Projected peak RPS × headroom
/ 單台經壓測確認的 safe RPS切換前確認:
- Auto Scaling Group 是否可直接擴容;優先使用既有 ASG,不先手動建立孤立 EC2。
- 各 AZ 至少有健康 target,且能承受一台故障。
- CPU、memory、PHP-FPM workers、DB connections、network。
- ALB
RequestCount、TargetResponseTime、HTTPCode_Target_5XX_Count、HealthyHostCount。 - queue worker、Redis、DB 與外部服務是否也會成為瓶頸。
可先用 30% headroom 當討論起點,實際門檻仍要由壓測與 production baseline 決定。若下一批預估流量會吃掉安全餘裕,或任一 instance 故障後無法承受 projected peak,就在切換前擴容。
七、執行順序
- 取得 AWS read-only 權限。
- 匯出 production/staging ALB、listener、rules、target groups 與 access-log 設定。
- 產生 legacy/new 全量 API inventory。
- 查 90 天 production ALB log,normalize method/path 並統計流量。
- 合併成
api_gap_inventory.csv,取得可信的剩餘數量。 - 從真實 Web/App request 建 Postman collection 與驗證矩陣。
- 以「正式流量 × parity/side-effect 風險」安排 rollout batches。
- 建立 PHP 8.2 單機容量 baseline,判斷是否先擴容。
- 每批依 staging → production → 監控 → 文件更新完成切換。
第一個實際工作不是修改 LB,而是先完成 production/staging LB 唯讀快照 + 90 天 API inventory。這兩份證據完成後,才能回答還剩多少 API、哪些已無流量,以及下一批是否需要增加機器。