設定
Webhook
永続的なアウトボックスによる ObjectOS からの外向きの Webhook。少なくとも 1 回の配信、HMAC 署名、上限付きの再試行、そして受信側が処理しなければならないこと。
対応エディション
ObjectOS は、外向きの Webhook に永続的なアウトボックスモデルを使います。Webhook プラグインが有効なとき、業務上の変更は配信の行をキューに入れ、バックグラウンドのディスパッチャーが再試行しながらそれを配信します。そのため、遅い、または利用できない受信側が、元のトランザクションをブロックすることはありません。
Webhook を有効にする
Webhook は省略可能な機能です。デプロイされる ObjectOS のイメージに @objectstack/plugin-webhooks が含まれていなければならず、アプリケーションの成果物は Webhook のサブスクリプションを登録しなければなりません(通常は sys_webhook オブジェクトのレコードとして)。
有効にすると、Setup に 2 つのオブジェクトが表示されます。
| オブジェクト | 目的 |
|---|---|
sys_webhook | Webhook のサブスクリプション(送信先 URL、イベントのフィルター、シークレット、ステータス) |
sys_webhook_delivery | 配信ログ(URL、レスポンスコード、試行回数、再試行のタイムスタンプ) |
配信の意味
- 少なくとも 1 回。 一時的な失敗の後、配信が再試行されることがあります。受信側は冪等でなければなりません。
- 永続的。 配信は業務データベースに保存されるので、ObjectOS の再起動を越えて残ります。
- パーティション分割。 各ディスパッチャーのワーカーはアウトボックスのパーティションを担当するので、デプロイメントは二重配信なしにディスパッチを水平にスケールできます。
- 上限付きの再試行。 失敗した配信は、設定可能な上限までバックオフしながら再試行されます。上限に達した行は、調査のために
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));
}シークレットをローテーションするには、新しいシークレットで新しいサブスクリプションを発行し、移行期間の間は両方を動かし、その後古いものを無効にします。
受信側に期待されること
- 数秒以内に
2xxで応答します。408、429、5xxのレスポンス(またはタイムアウト / トランスポートのエラー)は再試行可能で、バックオフしながら再試行されます。それ以外の4xxは恒久的な失敗として扱われ、それ以上再試行されずにdeadへ移されます。 - ディスパッチャーは
2xxを確認するまで配信を成功とマークしないので、受信側が失敗すると、調査や再配信のために行がsys_webhook_deliveryに残ります。 - 冪等にします。
X-Objectstack-Deliveryヘッダー(配信 ID)か、ペイロード内の独自のイベント ID で重複を排除してください。
失敗への対処
何かが失敗したとき:
sys_webhook_deliveryでその行を確認します。status、response_code、response_body、attemptsが記録されています。- ObjectOS から受信側への外向きのネットワークアクセスを確認します。
- 受信側が恒久的に変更された場合は、サブスクリプションの URL を更新し、Setup からその行を再配信します。
- インシデントのレビューのために、監査ログ(
sys_audit_log)はサブスクリプションの編集を記録しますが、ペイロードは記録しません。ペイロードはアウトボックスに残ります。
運用のヒント
- Webhook の URL にシークレットを入れないでください(クエリ文字列はログに記録されます)。
- 専用の受信側ホスト名を使うと、メインのアプリに影響を与えずに、エッジでそれをブロックして負荷を切り離せます。
- ディスパッチャーの遅延を監視します。アウトボックスが増え続けているなら、たいていは受信側の性能が落ちています。