配置
Webhooks
出站 webhook 投遞、簽名與重試。
ObjectOS 為出站 webhook 採用持久化的 outbox 模型。當 webhook 外掛啟用時,業務變更會將一條投遞記錄入隊,由後臺 dispatcher 帶重試地完成投遞——因此響應緩慢或不可用的接收方永遠不會阻塞發起方事務。
啟用 webhooks
Webhooks 是一項可選能力。部署的 ObjectOS 映象必須包含 @objectstack/plugin-webhooks,並且應用 artifact 必須註冊 webhook 訂閱(通常作為 sys_webhook 物件的記錄)。
啟用後,Console 中會出現兩個物件:
| 物件 | 用途 |
|---|---|
sys_webhook | Webhook 訂閱(目標 URL、事件過濾器、secret、狀態) |
sys_webhook_delivery | 投遞日誌(URL、響應碼、嘗試次數、重試時間戳) |
投遞語義
- 至少一次。 投遞在發生瞬時失敗後可能被重試;接收方必須是冪等的。
- 持久化。 投遞記錄會在 ObjectOS 重啟後保留,因為它們儲存在業務資料庫中。
- 分割槽。 每個 dispatcher worker 認領 outbox 的一個分割槽,使部署能夠橫向擴充套件投遞而不會重複投遞。
- 有界重試。 失敗的投遞會以退避策略重試,直至達到可配置的上限;耗盡重試的記錄會保留在
sys_webhook_delivery中以供檢查。
簽名
每次投遞都攜帶標識性請求頭,使接收方能夠路由、去重並校驗它:
X-Objectstack-Event: <event type, e.g. data.record.created>
X-Objectstack-Delivery: <delivery id — use as your idempotency key>
X-Objectstack-Attempt: <attempt number, starting at 1>當 webhook 訂閱設定了 secret 時,ObjectOS 還會為每個請求籤名:
X-Objectstack-Signature: sha256=<hex hmac>簽名為 HMAC-SHA256(secret, body),基於原始請求體計算。在接收端信任載荷前先校驗它:
import { createHmac, timingSafeEqual } from 'node:crypto';
function verify(body, signatureHeader, secret) {
const expected = 'sha256=' + createHmac('sha256', secret).update(body).digest('hex');
return timingSafeEqual(Buffer.from(signatureHeader), Buffer.from(expected));
}輪換 secret 的方式:使用新 secret 建立一個新訂閱,在過渡期同時執行兩者,然後停用舊訂閱。
對接收方的要求
- 在數秒內返回
2xx。408、429或5xx響應(或超時/傳輸錯誤)是可重試的,會以退避策略重試。任何其他4xx都被視為永久性失敗,並在不再重試的情況下轉入dead。 - 在看到
2xx之前,dispatcher 不會將投遞標記為成功,因此失敗的接收方會使該記錄保留在sys_webhook_delivery中,以供檢查或重新投遞。 - 保持冪等——基於
X-Objectstack-Delivery請求頭(delivery id)或你自己在載荷中的 event id 去重。
失敗處理
出錯時:
- 檢查
sys_webhook_delivery中的記錄——status、response_code、response_body與attempts均有記錄。 - 確認從 ObjectOS 到接收方的出站網路可達。
- 如果接收方永久變更了,更新訂閱 URL 並從 Console 重新投遞該記錄。
- 用於事件覆盤:審計日誌(
sys_audit_log)記錄訂閱編輯,但不記錄載荷——載荷保留在 outbox 中。
運維建議
- 不要把 secret 放進 webhook URL(query string 會被記錄)。
- 使用獨立的接收方主機名,便於在邊緣遮蔽以解除安裝流量時不影響主應用。
- 關注 dispatcher 滯後——outbox 不斷增長通常意味著接收方降級。