API Response Contract
文件狀態:已對 legacy migration 實務
最後驗證:2026-05-14
來源:quote_bids/change_status/reviews migration response shape 修正
這份文件回答什麼
這份文件規範 legacy API 搬到 new API 時,response 格式要如何比對與保護。
重點不是「成功或失敗語意看起來一樣」就算完成,而是 response shape 也要一致。欄位是否存在、欄位名稱、大小寫、型別、空值、錯誤碼與 message 都是 API contract。
不回答什麼
- 不整理單支 API 的完整 business rule。
- 不取代 repo 內的 migration detail 文件。
- 不定義新 API 的全域 response 標準。
核心規則
Legacy-compatible endpoint 必須以 legacy response 為準。
如果 legacy 成功只回:
{
"status": "Success"
}new API 就不能自行加成:
{
"status": "Success",
"error": 0
}即使 error: 0 在其他 endpoint 或其他 filter 很常見,也不能拿來推論這支 API 可以新增。
為什麼新增欄位也算破壞相容
新增欄位看似 harmless,但前端、App、SDK 或測試可能有以下行為:
- 嚴格比對 response JSON。
- 用
error是否存在判斷錯誤流程,而不是只看值。 - 把
status當唯一成功欄位。 - 對不同 filter 做不同 fallback。
- 把 response 原樣傳給其他流程或分析工具。
所以 migration 時不能把「多一個欄位通常沒差」當假設。
必查項目
搬移 legacy endpoint 前,至少要確認:
- 成功 response 是否有
error欄位。 - 成功 response 的
status值與大小寫。 - 失敗 response 的
error型別與 code。 - 失敗 response 的 message 欄位名稱,例如
status/message/error_message。 - 特定成功情境是否有額外欄位,例如
completed_on、closed_on、bank_result_code。 - 空 request / guard fail 是否 early return,且 response 是否比一般 catch 少欄位。
實作規則
- 不要用其他 API 的 response pattern 猜這支 API。
- 不要因為 controller helper 常見
error=0就補上。 - 不要把 PHPUnit 寫成期待「新標準」,測試應該鎖 legacy response。
- 若要刻意改善 response 格式,必須明確標記為 breaking / product decision,不能混在 migration commit。
- migration docs 的 curl 範例必須跟實際 legacy response shape 一致。
測試規則
成功 response 如果 legacy 沒有 error,測試要明確寫:
$this->assertSame('Success', $response['status']);
$this->assertArrayNotHasKey('error', $response);不要寫:
$this->assertSame(0, (int)$response['error']);這會把不存在的欄位誤改成新 contract。
反例:reviews migration
/quote_bids/change_status/reviews/{quote_bid_id}.json 的 legacy 一般成功 response 是:
{
"status": "Success"
}不能回:
{
"status": "Success",
"error": 0
}雖然同一支 legacy controller 的其他 change_status filter 可能會回 error: 0,但 reviews 分支一般成功只設定 status,最後直接輸出 $gen_bids。
Review Checklist
送出 migration commit 前,逐項確認:
- legacy code 中該 filter / action 的最後 response 寫法已讀過。
- 專案 migration detail 有列成功與失敗 response 範例。
- PHPUnit 有鎖 response shape,不只鎖 side effect。
- 實測 curl response 與 legacy shape 一致。
- 若 response shape 與 legacy 不同,commit message 和文件有明確說明原因。