すべての記事
webhook debuggingreplaytestingcallbacks

Webhookリプレイ: 再送せずにデバッグする

Webhookリプレイは、上流プロバイダーにイベントを再配信させることなく、以前捕捉したHTTPコールバックをローカルハンドラへ再送します。Stripeの課金、GitHubのプッシュ、Twilioのメッセージを再発生させる代わりに、リクエスト履歴からまったく同じリクエスト(ヘッダーもボディも全部)をリプレイします。

なぜWebhookリプレイが重要なのか

Webhookのデバッグはたいてい面倒なループになります。イベントを発生させ、配信を確認し、バグを見つけ、コードを直し、また発生させる。上流イベントの再発生は遅く、ノイズが多く、ときに不可能です(一度きりの課金イベント、削除済みリソース、レート制限のあるテストAPIなど)。

リプレイはそのループを縮めます。一度捕捉し、ハンドラを直し、通るまで同じペイロードをリプレイする。外部プロバイダーに一切触れずに済みます。

Webhookリプレイの仕組み

  1. コールバックがトンネルURLに届き、ローカルアプリへ転送されます。
  2. トンネルツールがリクエスト全体(メソッド、パス、ヘッダー、ボディ)を捕捉します。
  3. 捕捉したリクエストを見て、ハンドラのコードを修正します。
  4. 捕捉したリクエストをワンアクションでローカルエンドポイントへリプレイします。
  5. ハンドラが正しいレスポンスを返すまで繰り返します。

このワークフローには、単なるトラフィック転送ではなく、リクエスト捕捉を内蔵したlocalhostトンネルが必要です。

Webhookリプレイのユースケース

ハンドラ開発

Webhookハンドラを反復的に構築・テストします。パースロジックを磨きながら、同じStripeのcheckout.session.completedイベントを10回リプレイします。

冪等性テスト

プロバイダーはリトライ時に重複イベントを配信します。同じペイロードを何度もリプレイして、二重課金や重複レコードを生まずに重複を安全に処理できることを確認します。

署名検証のデバッグ

署名チェックが失敗したら、ヘッダーをそのままにした元のリクエストをリプレイし、問題が検証ロジックにあるのかペイロードのパースにあるのかを切り分けます。

リグレッションテスト

本番に近いテストイベントの捕捉済みリクエストを保存し、リファクタ後にリプレイして、デプロイ前に破壊的変更を検出します。

PortPreviewでのWebhookリプレイ

  1. アプリを起動し、npx portpreview 3000を実行します。
  2. プロバイダーがトンネルURLへコールバックを送るよう設定します。
  3. テストイベントを発生させ、PortPreviewで捕捉したリクエストを確認します。
  4. ハンドラを修正し、捕捉したリクエストをリプレイします。
  5. プロバイダーを再発生させずに、レスポンスのステータスとボディを確認します。

PortPreviewは元のヘッダーを保持するため、リプレイ中もプロバイダーの署名検証が意味を保ちます。

リプレイ vs 再発生: どちらを使うか

  • リプレイ: ハンドラのロジックバグ、ペイロードのパース、冪等性チェック、署名デバッグ。
  • 再発生: プロバイダー側のイベント生成のテスト、Webhook登録の検証、ライブなプロバイダー状態とのエンドツーエンド統合。

プロバイダー別の設定は、StripeのWebhookローカルテストGitHubのWebhookローカルテストTwilioのWebhookローカルテストのガイドを参照してください。

Webhookリプレイのベストプラクティス

  • 初回配信だけでなく、リプレイ時にも必ず署名を検証する。
  • 同じイベントを複数回リプレイして重複配信をテストする。
  • リグレッションチェックのため、featureブランチ中はリクエスト履歴を保持する。
  • リプレイしたイベントが本番データに影響しないよう、テストモードの認証情報を使う。

Webhookの捕捉とリプレイをトンネルワークフローに組み込むには、PortPreviewのウェイトリストに登録してください。

よくある質問

Webhookリプレイとは何ですか?
Webhookリプレイは、以前捕捉したコールバックリクエストを、上流プロバイダーを再発生させずにローカルハンドラへ再送します。リクエスト履歴のヘッダーとボディをそのまま再利用します。
なぜイベント再発生よりWebhookリプレイの方が良いのですか?
リプレイは即時で、プロバイダーのレート制限、一度きりのイベント、テストAPIの可用性に依存しません。外部システムを待たずにハンドラコードを反復できます。
Webhookリプレイは署名ヘッダーを保持しますか?
はい。トンネルツールが元のリクエストをそのまま捕捉してリプレイすればOKです。PortPreviewはヘッダーを保持するため、Stripe、GitHubなどの署名チェックがリプレイ中も機能します。