Webhookの仕組み ― ポーリングとの違いからセキュリティまで


ポーリング vs Webhook ポーリング(従来型) クライアント サーバー 新着ある? ないよ 新着ある? ないよ 新着ある? あるよ! 無駄なリクエストが多い Webhook(イベント駆動) サーバー 受信側 イベント発生 HTTP POST { "event": "push", "repo": "my-app" } 200 OK HMAC署名で検証 必要なときだけ通知 ― 効率的!
ポーリングとWebhookの比較イメージ
ひよこ ひよこ

Webhookって何なの? フックって釣り針のこと?

ペンギン先生 ペンギン先生

いい連想だね!Webhookは「イベントが起きたらHTTP通知してくれる仕組み」だよ。普通のAPIはこっちから聞きに行くけど、Webhookは相手から教えてくれる「逆方向のAPI」なんだ。電話で例えると、自分からかけるんじゃなくて、相手が用事があるときにかけてきてくれる感じだね。

ひよこ ひよこ

自分から聞きに行くやり方もあるんだよね?

ペンギン先生 ペンギン先生

それがポーリングだよ。「新しい注文ある?」「ない」「新しい注文ある?」「ない」…って定期的に聞き続けるんだ。無駄なリクエストが多くてサーバーに負荷がかかるし、リアルタイム性も低い。Webhookなら「注文が入ったよ!」ってすぐ教えてくれるから効率的なんだ。

ひよこ ひよこ

具体的にはどうやって動くの?

ペンギン先生 ペンギン先生

まず受信側が「このURL通知して」と登録するよ。たとえばGitHubで「pushされたら https://myapp.com/webhook に通知」と設定する。するとpushイベントが起きたとき、GitHubがそのURLHTTP POSTでJSON形式のデータを送ってくれるんだ。

ひよこ ひよこ

送られてくるデータにはどんな情報が入ってるの?

ペンギン先生 ペンギン先生

ペイロード(payload)って呼ばれるJSONデータで、イベントの種類や詳細が入ってるよ。GitHubなら「誰が」「どのブランチに」「何をpushしたか」、Stripeなら「どの顧客の」「いくらの決済が」「成功したか」みたいな情報だね。Slack通知CI/CD自動起動にも使われてるよ。

ひよこ ひよこ

誰でもそのURLにデータを送れちゃうんじゃないの? セキュリティは大丈夫?

ペンギン先生 ペンギン先生

いい質問!HMAC署名っていう仕組みで検証するよ。送信側と受信側で秘密のトークンを共有しておいて、送信側がペイロードからHMAC-SHA256のハッシュ値を計算してヘッダーに付ける。受信側も同じ計算をして、一致すれば「本物の通知だ」と分かるんだ。

ひよこ ひよこ

通知先のサーバーが落ちてたらどうなるの?

ペンギン先生 ペンギン先生

多くのWebhook送信側はリトライ機能を持ってるよ。HTTPステータスが200以外だったら、指数バックオフ(1分後→5分後→30分後…)で再送するんだ。受信側は同じ通知が複数回届く可能性があるから、べき等性キー(idempotency key)で重複処理を防ぐ設計が大事だよ。

ひよこ ひよこ

それでもずっと届かなかったらどうするの?

ペンギン先生 ペンギン先生

デッドレターキュー(DLQ)っていう仕組みを使うことがあるよ。何回リトライしても失敗した通知を専用のキューに溜めておいて、あとで原因を調査・再処理できるようにするんだ。本番環境では通知の取りこぼしが致命的になることもあるから、こういう設計が重要なんだよ。

ひよこ ひよこ

WebSocketServer-Sent Eventsとは何が違うの?

ペンギン先生 ペンギン先生

WebSocketは双方向のリアルタイム通信で、チャットみたいに常時接続が必要な場面向き。SSE(Server-Sent Events)はサーバーからクライアントへの一方向ストリーム。Webhookはイベントごとに独立したHTTPリクエストで、接続を維持しなくていいのが特徴だよ。サーバー間の連携にはWebhookが一番シンプルで使いやすいんだ。

ひよこ ひよこ

Webhookを設計するときに気をつけるべきことって他にもあるの?

ペンギン先生 ペンギン先生

順序保証がないことは意識しておくべきだね。ネットワーク遅延やリトライで、イベントAの通知よりイベントBの通知が先に届くことがあるんだ。タイムスタンプやシーケンス番号で順序を判定する仕組みを入れておくと安心だよ。あと、受信エンドポイントは5秒以内にレスポンスを返して、重い処理は非同期で行うのがベストプラクティスだね。