在使用 kintone 建置庫存管理系統、預約申請系統時,經常會遇到兩個共通的挑戰:
只要其中一個環節沒有妥善處理,就可能導致資料不一致的問題,例如:
為了處理這類「需要同時更新多筆、甚至跨多個應用程式資料」的需求,kintone 提供了 bulkRequest API,讓多個 REST API 請求可以被當成「同一次處理」來執行。
本文將以庫存管理為例,說明在實務上可能遇到的問題,以及如何搭配 bulkRequest + revision,確保資料的一致性。
bulkRequest 允許你在一次呼叫中,對多個應用程式同時執行多個 kintone REST API。官方文件列出的可執行 API 包含:新增/更新/刪除記錄、更新狀態、更新作業者等。
🔗 官方文件:Bulk Request
一次 bulkRequest 最多可以放 20 個子請求。
bulkRequest 的重要特性是:
只要其中一個子請求失敗,後續子請求不會執行,並且整組處理會回滾。
本文後續將介紹的庫存範例,就是靠這個特性確保「出入庫紀錄」與「在庫數」不會只更新一半。
https://{subdomain}.cybozu.com/k/v1/bulkRequest.json
https://{subdomain}.cybozu.com/k/guest/{GUEST_SPACE_ID}/v1/bulkRequest.json
bulkRequest 只能對「同一個訪客空間內」的應用程式做批次處理;不能跨訪客空間、也不能把訪客空間 app 跟一般 app 混在同一次 bulkRequest。
所有執行子請求 API 所需要的權限。
(本質上就是「你要執行的那些 API 本來就需要的權限」。)
需要準備各 app 的 token,並在 header 一次帶多組 token。
bulkRequest 的 body 核心只有一個:requests 陣列,每個元素包含:
method:HTTP methodapi:要呼叫的 API 路徑(例如 /k/v1/record.json)payload:該 API 原本要送的 body回傳會 results 陣列,陣列中包含每一個請求的 result 物件,順序與 requests 一致。
result 物件都會有對應 API 的結果result 物件會有 error 內容,其他會是 {}(空物件)假設我們有以下兩個應用程式:
每次進行出入庫時,實際上都需要同時完成兩件事:
假設商品 A 目前的庫存數是 10 個。
正常情況下,如果依序進行以下操作:
結果是合理的。
但如果兩個人幾乎同時操作,流程可能變成這樣:
最終庫存變成 2 個,完全忽略了山田的入庫操作。
這正是典型的「同時更新導致資料被覆蓋」的問題。
再來看另一個常見問題。
一次出入庫操作,實際上包含兩個 API 請求:
如果發生以下情況:
那麼系統就會留下不一致的狀態:
有出入庫記錄,卻沒有正確反映到庫存數量。
$revision在進行更新前,先從「庫存管理」應用程式取得目前的庫存數量。
GET /k/v1/record.json?app={庫存管理AppID}&id=1
回傳結果中,除了實際欄位資料外,還會包含一個特殊欄位:
"$revision": {
"type": "__REVISION__",
"value": "17"
}
revision 可以理解為記錄的「版本號碼」:
💡 使用「更新記錄狀態的 API」時,由於包含「執行流程動作」與「更新狀態」兩個操作,revision 會增加 2。詳情請參考 官方文件 說明。
接著,使用 bulkRequest 一次送出兩個請求:
POST /k/v1/bulkRequest.json
{
"requests": [
{
"method": "PUT",
"api": "/k/v1/record.json",
"payload": {
"app": {庫存管理AppID},
"id": 1,
"revision": 17,
"record": {
"在庫數": {
"value": "15"
}
}
}
},
{
"method": "POST",
"api": "/k/v1/record.json",
"payload": {
"app": {出入庫記錄AppID},
"record": {
"入庫數": {
"value": "5"
}
}
}
}
]
}
同前述說明,執行 bulkRequest 時,若有任何一個請求失敗,後續請求便不會執行,並且所有的請求回滾至原先的狀態。
如果在取得庫存資料後,有其他人先更新了該筆記錄,則庫存更新會失敗。
並且因為 bulkRequest 的回滾機制,出入庫記錄也不會被新增。
這樣就能同時解決:
本文介紹了如何在 kintone 中:
這樣的設計非常適合用在:
不過也要注意,如果同一筆記錄的更新頻率非常高,使用 revision 的方式會讓 API 發生錯誤的機率提高,實務上仍需評估是否適合用 kintone 來實作此類系統。