ふくふくHukuhuku Inc.
EP.35Data Fetch 10分公開: 2026-09-02

取りに行かずに受け取る ── Webhook を使うときの注意

定期的に問い合わせる方式は、無駄と遅れの両方を抱えます。相手から通知してもらえるなら、そちらのほうが速くて軽い。ただし受け取る側の責任が増えます。

#Webhook#設計#運用
執筆 / 監修
松尾 亮合同会社ふくふく 代表社員

データ基盤・データパイプライン構築 / BI / 生成 AI 活用支援を専門とするエンジニア (28 年)。 本記事は AI 利用ポリシーに基づき、生成 AI の補助で執筆 → 人間が監修・編集して公開しています。

プロフィール詳細
シェア

ここまでは、こちらから取りに行く方式を扱ってきました。定期的に問い合わせて、変わっていれば取る。単純で分かりやすい形ですが、2つの無駄があります。変わっていないときも問い合わせることと、変わってから気づくまで時間がかかることです。

は、この向きを逆にします。相手側で変化が起きたときに、向こうから通知が飛んでくる。無駄な問い合わせが消え、反映も速くなります。

ただし、受け取る側には新しい責任が生まれます。常に受け取れる状態を保つことと、同じ通知が2回来ても壊れないことです。取りに行く方式では考えなくてよかった問題が出てきます。

同じ通知が2回来る

通知の送り主は、届いたかどうかを応答で判断します。こちらが処理に成功していても、応答を返す前に接続が切れれば、相手には失敗に見えます。すると同じ通知がもう一度送られてきます。

だから受け取る側にはが要ります。同じ通知を2回処理しても、結果が変わらないようにする。通知には一意の識別子が付いていることが多いので、処理済みの識別子を覚えておくのが基本形です。

処理済みの識別子を記録し、2回目は何もしない
Python
import sqlite3from pathlib import Path
DB = Path("data/webhook_seen.sqlite")

def init(db_path: Path = DB) -> None:    db_path.parent.mkdir(parents=True, exist_ok=True)    with sqlite3.connect(db_path) as con:        con.execute("CREATE TABLE IF NOT EXISTS seen (event_id TEXT PRIMARY KEY)")

def mark_if_new(event_id: str, db_path: Path = DB) -> bool:    """初めて見る通知なら True。すでに処理済みなら False。
    主キーの制約で二重登録を防ぐので、確認と登録の間に    別の処理が割り込んでも二重に処理されない。    """    with sqlite3.connect(db_path) as con:        try:            con.execute("INSERT INTO seen (event_id) VALUES (?)", (event_id,))        except sqlite3.IntegrityError:            return False    return True

通知の本文には、変化した内容がすべて入っているとは限りません。「この識別子のものが更新された」とだけ書かれていて、中身は改めてで取りに行く形が一般的です。通知は合図であって、データそのものではないと考えておくほうが安全です。

受け取った通知は、処理する前にへそのまま保存してください。後から「本当にその通知が来ていたのか」を確かめられます。送り主と食い違ったときに、証拠が無いと話が進みません。

受け取り口は誰でも叩ける

通知を受け取る口は、インターネットから見える場所に置くことになります。つまり送り主以外も叩けます。偽の通知を送られると、存在しないデータを処理してしまいます。

で 200 を返しさえすれば受理されるので、検証を省いても動いてしまいます。多くのサービスは、通知に署名を付けています。共有の秘密を使って本文から署名を計算し、送られてきた署名と一致するかを確かめることで、本物かどうかを判定できます。この検証を省略してはいけません。

署名を検証する。比較には時間差の出ない関数を使う
Python
import hashlibimport hmac

def verify_signature(body: bytes, signature: str, secret: str) -> bool:    """本文から署名を計算し、送られてきたものと一致するか確かめる。
    == で比べると、一致しない位置によって処理時間が変わり、    それを手がかりに署名を推測されうる。専用の関数を使う。    """    expected = hmac.new(secret.encode("utf-8"), body, hashlib.sha256).hexdigest()    return hmac.compare_digest(expected, signature)
受け取ったら、まず保存して即座に応答する

通知の送り主は、応答が遅いと失敗とみなして再送します。受け取った本文をそのまま保存して、すぐに成功を返す。中身の処理は後回しにする。この形にしておかないと、処理が重い日に再送が積み重なります。

取りこぼしに気づけない

通知方式の弱点は、来なかったことに気づけないことです。取りに行く方式なら、取れなければ失敗として分かります。通知は、送られてこなければ何も起きないだけです。相手側の障害でも、こちらの受け取り口が落ちていても、静かに欠けます。

だから通知方式を採るときも、定期的に取りに行く仕組みを併用するのが安全です。1日1回、全体を突き合わせて欠けがないかを確認する。通知で速さを取り、定期取得で確実さを担保する、という組み合わせになります。

受け取り口を用意して運用し続けるのは、それなりの負担です。更新の速さが本当に必要かを先に考えてください。1日1回で足りるなら、取りに行く方式のほうが簡単で壊れにくい。次回は、その定期実行の組み方を扱います。

通知方式は、速さと引き換えに運用の手間が増えます。取りに行く方式で足りるなら、無理に切り替える必要はありません。

受け取り口を公開したままにしておくと、使わなくなった後も外から叩かれ続けます。役目を終えたら閉じる。これは取得の棚卸しとして、後の回でまとめて扱います。

取りに行く方式と受け取る方式は、どちらが優れているという話ではありません。更新の速さがどれだけ必要かで決まります。速さが要らない場面で通知方式を選ぶと、運用の手間だけが増えます。

シェア

この記事の感想を教えてください

あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。

シリーズの外も探す:

まずは、現状を聞かせてください。

要件が固まっていなくて大丈夫です。現状診断と方針提案までを無料でお手伝いします。

無料相談フォームへ hello [at] hukuhuku [dot] co [dot] jp