Webhook 入門:システム間の自動連携を実現する技術
はじめに
現代の Web サービスやアプリケーションは、さまざまなシステムと連携しながら動作しています。例えば、EC サイトで注文が入ったときに自動的に在庫管理システムに通知したり、GitHub にコードがプッシュされたときに自動的にビルドを開始したりする仕組みが必要です。
このような「あるシステムで特定のイベントが発生したときに、別のシステムに自動的に通知する」仕組みを実現する技術として、Webhookが広く使われています。
本記事では、Webhook の基本概念、API との違い、実装方法、活用例など、初心者にもわかりやすく解説します。
Webhook とは何か?
Webhook の定義
Webhookとは、あるシステム(送信側)で特定のイベントが発生したときに、別のシステム(受信側)に対して自動的に HTTP リクエストを送信する仕組みです。
簡単に言えば、「何か起きたら自動的に教えてくれる」仕組みです。
メール購読の例え
Webhook を理解するために、メールマガジンの購読を例に考えてみましょう:
- メール購読の場合:
- あなたがメールマガジンを購読する
- 発行者が新しい記事を書く
- 発行者があなたにメールを送信する
- あなたがメールを受け取る
- Webhook の場合:
- あなた(受信側)がサービス(送信側)に Webhook の URL を登録する
- サービス側で何か重要なイベントが発生する
- サービスがあなたの登録した URL にデータを送信する
- あなたのシステムがそのデータを受け取って処理する
API と Webhook の違い
API と Webhook は似ているようで異なる概念です。主な違いは以下の通りです:
| 特徴 | API | Webhook |
|---|---|---|
| 通信の方向 | クライアントからサーバーへ(プル型) | サーバーからクライアントへ(プッシュ型) |
| 主導権 | クライアント側 | サーバー側(イベント発生時) |
| 目的 | データや機能の利用 | イベント通知 |
| タイミング | クライアントが必要なときに呼び出す | イベント発生時に自動的に呼び出される |
| 実装 | エンドポイントを提供する側 | エンドポイントを受け取る側 |
API と Webhook の関係を例えると:
- API:あなたが図書館に行って本を借りる(あなたが主体的に行動)
- Webhook:図書館があなたの予約した本が入荷したら連絡してくれる(図書館が主体的に行動)
Webhook の仕組み
Webhook の基本的な仕組みは以下の通りです:
- 登録:受信側のシステムが、送信側のシステムに Webhook URL を登録する
- イベント発生:送信側のシステムで特定のイベントが発生する
- 通知:送信側のシステムが、登録されている Webhook URL に HTTP POST リクエストを送信する
- 処理:受信側のシステムがリクエストを受け取り、必要な処理を行う
一般的な Webhook の流れを図示すると以下のようになります:
[送信側システム] -- イベント発生 --> [HTTP POST] --> [受信側システム(Webhook URL)]
|
v
[イベントデータ]
|
v
[処理の実行]
送信されるデータ
Webhook で送信されるデータは通常、JSON 形式で以下のような情報が含まれます:
- イベントの種類(例:
order.created、payment.succeededなど) - イベントが発生した時刻
- イベントに関連するデータ(注文情報、支払い情報など)
例えば、EC サイトの注文イベントの Webhook データは以下のようになります:
{
"event_type": "order.created",
"created_at": "2024-09-05T10:30:00Z",
"data": {
"order_id": "ORD12345",
"customer": {
"id": "CUST789",
"name": "山田太郎",
"email": "yamada@example.com"
},
"items": [
{
"product_id": "PROD001",
"name": "商品A",
"quantity": 2,
"price": 1000
},
{
"product_id": "PROD002",
"name": "商品B",
"quantity": 1,
"price": 1500
}
],
"total": 3500,
"status": "pending"
}
}
Webhook の実装方法
受信側(Webhook を受け取る側)の実装
Webhook を受け取るためには、公開された Web サーバーとエンドポイント(URL)が必要です。以下は、Node.js と Express を使った簡単な Webhook 受信サーバーの例です:
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
// JSONリクエストのパース
app.use(bodyParser.json());
// Webhookエンドポイント
app.post("/webhooks/orders", (req, res) => {
const event = req.body;
console.log("Webhookを受信しました:", event);
// イベントの種類によって処理を分岐
if (event.event_type === "order.created") {
processNewOrder(event.data);
} else if (event.event_type === "order.updated") {
updateOrderStatus(event.data);
} else if (event.event_type === "order.cancelled") {
cancelOrder(event.data);
}
// 送信元には200 OKを返す(処理成功を通知)
res.status(200).send("Received");
});
// 注文処理の関数
function processNewOrder(orderData) {
// 注文処理のロジック
console.log(`注文ID: ${orderData.order_id}を処理しています`);
// 例: データベースに保存、在庫の確認、メールの送信など
}
function updateOrderStatus(orderData) {
// 注文状態更新のロジック
console.log(`注文ID: ${orderData.order_id}の状態を更新しています`);
}
function cancelOrder(orderData) {
// 注文キャンセルのロジック
console.log(`注文ID: ${orderData.order_id}をキャンセルしています`);
}
// サーバー起動
app.listen(3000, () => {
console.log("Webhookサーバーがポート3000で起動しました");
});
送信側(Webhook を送信する側)の実装
送信側のシステムでは、特定のイベントが発生したときに Webhook を発火させる必要があります。以下は、イベントが発生したときに Webhook を送信する簡単な実装例です:
const axios = require("axios");
// Webhookを送信する関数
async function sendWebhook(webhookUrl, eventType, eventData) {
try {
// Webhook用のペイロードを作成
const payload = {
event_type: eventType,
created_at: new Date().toISOString(),
data: eventData,
};
// HTTP POSTリクエストを送信
const response = await axios.post(webhookUrl, payload, {
headers: {
"Content-Type": "application/json",
"X-Webhook-Signature": generateSignature(payload, SECRET_KEY),
},
});
console.log("Webhook送信成功:", response.status);
return true;
} catch (error) {
console.error("Webhook送信失敗:", error.message);
return false;
}
}
// 署名を生成する関数(セキュリティのため)
function generateSignature(payload, secretKey) {
const crypto = require("crypto");
return crypto
.createHmac("sha256", secretKey)
.update(JSON.stringify(payload))
.digest("hex");
}
// 注文作成時にWebhookを送信する例
function createOrder(orderData) {
// 注文をデータベースに保存するなどの処理
// ...
// 登録されているすべてのWebhook URLに通知
const webhookUrls = getWebhookUrlsForEvent("order.created");
for (const url of webhookUrls) {
sendWebhook(url, "order.created", orderData);
}
}
Webhook の活用例
Webhook は様々な場面で活用されており、システム間の連携を自動化する強力な手段となっています。以下はよくある活用例です:
1. EC(電子商取引)システム
- 新規注文が入ったときに在庫管理システムに通知
- 支払いが完了したときに出荷システムに通知
- 商品が発送されたときに顧客にメール通知
2. CI/CD(継続的インテグレーション/デリバリー)
- GitHub や GitLab でコードがプッシュされたときに自動ビルド開始
- プルリクエストが作成されたときにコード品質チェックを実行
- デプロイが完了したときに Slack や Teams に通知
3. 支払い処理
- Stripe、PayPal などの決済サービスで支払いが完了したときに通知
- サブスクリプションの更新や失敗時の通知
- 不正利用の検知時のアラート
4. コミュニケーションツール連携
- チケット管理システムでタスクが割り当てられたときに Slack に通知
- CRM で重要な顧客の活動があったときにメール通知
- カレンダーで予定が追加されたときにリマインダー送信
5. IoT(モノのインターネット)デバイス
- センサーが特定の閾値を検知したときにアラートシステムに通知
- デバイスのステータスが変更されたときに管理システムに通知
- 位置情報が更新されたときに追跡システムに通知
主な Webhook 提供サービス
多くのサービスが Webhook を提供していますが、特に開発者向けに広く利用されているものをいくつか紹介します:
- GitHub Webhooks
- リポジトリの更新、Issue、Pull Request などのイベントを通知
- CI/CD パイプラインの自動化に活用
- Stripe Webhooks
- 支払い処理、サブスクリプション更新、請求書発行などのイベントを通知
- 詳細な支払いフローの自動化に活用
- Slack Webhooks
- 外部システムから Slack チャンネルにメッセージを送信
- アラートやステータス更新の通知に活用
- Shopify Webhooks
- 注文、商品、顧客に関するイベントを通知
- EC サイトとバックオフィスシステムの連携に活用
- Zapier Webhooks
- 様々なアプリケーション間の連携を簡単に構築
- コード不要で自動化フローを作成
Webhook の実装におけるベストプラクティス
Webhook を安全かつ効率的に実装するためのベストプラクティスを紹介します。
セキュリティ
- 署名検証
- 送信側がリクエストにデジタル署名(HMAC)を付加し、受信側で検証
- なりすましや改ざんを防止
// 署名検証の例(Node.js)
const crypto = require("crypto");
function verifyWebhookSignature(payload, signature, secretKey) {
const expectedSignature = crypto
.createHmac("sha256", secretKey)
.update(JSON.stringify(payload))
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expectedSignature),
Buffer.from(signature)
);
}
- HTTPS の使用
- 通信の暗号化のために HTTPS を必ず使用
- 平文でデータを送受信しない
- IP アドレス制限
- 可能であれば、Webhook を送信するサーバーの IP アドレスを制限
- 未知のソースからのリクエストをブロック
信頼性
- べき等性の確保
- 同じ Webhook イベントが複数回届いても問題ないように設計
- イベント ID を使用して重複処理を防止
- 応答の迅速化
- Webhook の受信確認は迅速に(処理結果を待たずにレスポンス)
- 重い処理はバックグラウンドで実行
- リトライ機構
- 送信側は失敗時に再試行する仕組みを実装
- 指数バックオフ(徐々に間隔を広げる)戦略の採用
// 指数バックオフによるリトライの例
async function sendWebhookWithRetry(url, payload, maxRetries = 5) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = await axios.post(url, payload);
return response; // 成功したらループを抜ける
} catch (error) {
// 失敗した場合
console.error(
`Webhook送信失敗 (${attempt + 1}/${maxRetries}):`,
error.message
);
if (attempt < maxRetries - 1) {
// リトライまでの待機時間を計算(指数バックオフ)
const waitTime = Math.pow(2, attempt) * 1000; // 1秒, 2秒, 4秒, 8秒...
console.log(`${waitTime}ミリ秒後にリトライします...`);
await new Promise((resolve) => setTimeout(resolve, waitTime));
} else {
throw new Error("最大リトライ回数に達しました");
}
}
}
}
設計
- 軽量なペイロード
- 必要最小限の情報のみを含める
- 大量データは参照用の ID や URL のみ送信
- 明確なイベント名
- イベント名は
resource.action形式が一般的 - 例:
order.created,user.updated,payment.failed
- バージョニング
- Webhook のフォーマットが変わる場合はバージョンを明示
- 例:
/webhooks/v1/orders,/webhooks/v2/orders
Webhook のデバッグとテスト
Webhook の開発とテストには以下のツールが役立ちます:
- ngrok
- ローカル環境のサーバーを一時的に公開 URL 化
- 開発中の Webhook エンドポイントのテストに最適
# ngrokのインストール(Macの場合)
brew install ngrok
# ローカルの3000ポートを公開
ngrok http 3000
- Webhook.site
- 一時的な Webhook エンドポイントを提供するオンラインサービス
- 受信した Webhook の内容を確認可能
- Postman
- Webhook のシミュレーション(手動で POST リクエスト送信)
- Webhook エンドポイントのテスト
- ログの活用
- Webhook の送受信を詳細にログに記録
- 問題発生時の原因特定に役立つ
// ロギングミドルウェアの例(Express)
app.use("/webhooks", (req, res, next) => {
console.log("Webhook受信:", {
timestamp: new Date().toISOString(),
path: req.path,
method: req.method,
headers: req.headers,
body: req.body,
});
next();
});
Webhook と関連技術
Webhook と関連する他の技術についても簡単に紹介します。
1. Server-Sent Events (SSE)
- サーバーからクライアントへの一方向のリアルタイム通信
- 標準的な HTTP を使用
- Webhook より頻繁な更新に適している
2. WebSocket
- クライアントとサーバー間の双方向リアルタイム通信
- 恒久的な接続を維持
- チャットやリアルタイムダッシュボードなど、より高頻度な通信に適している
3. メッセージキュー
- RabbitMQ, Apache Kafka, Amazon SQS など
- 信頼性の高いメッセージ配信を実現
- Webhook と組み合わせて堅牢なシステムを構築可能
Webhookの要点(システム間の自動連携)
Webhook は、システム間の自動連携を実現するための強力なツールです。「何か起きたら自動的に教えてくれる」という仕組みにより、効率的なシステム間連携が可能になります。
本記事のポイントをまとめると:
- Webhook は「イベント発生時に自動通知」するプッシュ型の通信
- API は「必要なときにデータを取得」するプル型の通信
- Webhook の基本的な仕組みは「登録 → イベント発生 → 通知 → 処理」
- EC、CI/CD、決済処理など、様々な場面で活用されている
- 実装時はセキュリティ(署名検証など)や信頼性(リトライ機構など)に注意
- ngrok や Webhook.site などのツールを使ってデバッグやテストを効率化
システム間の自動連携を考える際は、API と Webhook を適材適所で使い分けることが重要です。API は「必要なときにデータを取得する」のに対し、Webhook は「重要なイベントが発生したら即座に通知を受ける」という異なる特性を持っています。
Webhookの実装についてのご相談はこちら参考リソース
- GitHub Webhooks Documentation
- Stripe Webhooks Guide
- Webhook.site - Webhook テスト用ツール
- ngrok - ローカル環境のトンネリングツール
- Zapier Webhooks - Webhook と API を活用したノーコード連携ツール