批次端點

逐筆結果放在回應 body 裡,以及兩套不可混用的狀態字典

View as Markdown

客戶、商品、規格(SKU)、庫存各自提供一支批次端點,讓你一次寫入多筆資料,不必逐筆呼叫單筆端點。四支批次端點共用同一套「先擋空批次、受理後一律 200、逐筆各自回報成功或失敗」的模型,但逐筆狀態的字典分成兩組,混用會直接讓你的解析邏輯出錯——這是本頁的重點。

空陣列或沒有 body 會先被拒絕

送出空陣列 [],或請求完全沒有 body,會在受理前就被直接擋下,回傳 400 empty_batch。這個檢查發生在「受理」這個動作之前——被擋下的請求不算數,不會出現在下一節「一律 200」的規則裡。

四支批次端點都遵守同一條規則:

  • POST /v1/customers/batch
  • POST /v1/products/batch
  • POST /v1/skus/batch
  • POST /v1/skus/stock/batch

已受理的請求一律回傳 HTTP 200

只要陣列不是空的,這個請求就算已受理——批次端點永遠回傳 HTTP 200,即使陣列裡有一筆、甚至全部都處理失敗。逐筆的處理結果放在回應 body 的 items 裡,順序與送出的陣列相同;一筆失敗不會讓其他筆一起失敗,也不會讓整個請求失敗或改變外層的 HTTP 狀態碼。

201404409 這三個狀態碼只會出現在單筆端點(例如 POST /v1/customersPUT /v1/products/{id}PUT /v1/internal-users/{id})。批次端點不會回傳它們——批次端點對應的成功或失敗結果,一律藏在 200 回應的 items 裡,不會反映在 HTTP 狀態碼上。判斷批次裡某一筆有沒有成功,永遠是看那一筆的 status,不是看外層的 HTTP 狀態碼。

兩套逐筆狀態字典,不可混用

批次端點分兩種家族,逐筆結果的欄位形狀與狀態值完全不同:

端點狀態字典識別欄位錯誤欄位
POST /v1/customers/batchcreatedupdatedfailedindexerrors(陣列)
POST /v1/products/batchcreatedupdatedfailedindexerrors(陣列)
POST /v1/skus/batchcreatedupdatedfailedindexerrors(陣列)
POST /v1/skus/stock/batchokfailedskuIderror(字串或 null)

主檔批次:createdupdatedfailed

客戶、商品、規格三支主檔批次端點,逐筆結果的 status 只有三種小寫值:

status意義
created這一筆新增成功
updated這一筆更新成功——依 id 直接更新,或依 outerSysCode 去重更新,判斷規則見「Upsert 與冪等」
failed這一筆失敗,原因在 errors
POST /v1/products/batch 的回應
{
"items": [
{ "index": 0, "status": "created", "id": 101, "errors": [] },
{ "index": 1, "status": "updated", "id": 42, "errors": [] },
{ "index": 2, "status": "failed", "id": null, "errors": ["invalid_product_category_id"] }
]
}

index 是這一筆在送出陣列中的位置(從 0 起算);id 在成功時是新增或更新後的資料 id,失敗時是 nullerrors 在失敗時可能不只一則,成功時是空陣列。

庫存批次:okfailed

POST /v1/skus/stock/batch 是唯一的庫存批次端點,逐筆結果的 status 只有兩種小寫值,跟主檔批次完全不同,也沒有 created/updated 的區分——因為庫存的寫入永遠是覆蓋(絕對值快照),不是新增:

status意義
ok這一筆庫存更新成功
failed這一筆失敗,原因在 error
POST /v1/skus/stock/batch 的回應
{
"items": [
{ "skuId": 1, "status": "ok", "error": null },
{ "skuId": 2, "status": "failed", "error": "SKU not found" }
]
}

欄位名稱也不一樣:庫存批次用 skuId 識別、error 回報失敗原因(單一字串或 null);主檔批次用 index 識別、errors 回報失敗原因(陣列)。如果你打算寫一支共用的批次結果解析器同時處理主檔與庫存批次,這兩點差異都要處理,不能假設兩者共用同一個形狀。

下一步