Webhookは署名検証と即時応答を別々に設計する

しろまえ殿がWebhook(外部サービスから通知を受けるHTTP窓口)を組んだとき、最初に二つの境界を分けた。 誰から届いたかを確かめる境界と、いつ応答するかの境界だ。

受信時は本文とチャネルシークレットからHMAC-SHA256(秘密鍵を使う改ざん検知用の計算)を作り、X-Line-Signatureヘッダーと照合した。 一致しない通知は処理しない。 署名検証を省くと、誰でも窓口を呼べてしまう。

先に受け取り、重い処理は後ろへ回す

要約やファイル解析に数十秒かかるなら、Webhookへ先に200 OKを返す。 その後で重い処理を動かし、完了した結果はpush API(宛先へ後から送るAPI)で返す。 短時間だけ有効なreply用識別子(受信直後の返信に使う一時情報)を、遅い処理で使い回してはいけない。

PHP-FPM(常駐するPHP実行方式)のfastcgi_finish_request()は、応答を切り離すための仕組みだ。 PHP built-in server(開発用の簡易サーバー)では同じ動きにならない。 たとえば受付窓口で先に整理券を渡しても、窓口係が帰らなければ次の客は進めない。

開発環境の成功表示を信じすぎない

開発用トンネルは起動のたびにURLが変わることがある。 検証時に登録先を更新する運用を決めておく。

また、設定ファイルの単一ファイルマウントは環境によって失敗する。 502(ゲートウェイが奥のサービスから正しい応答を得られない状態)が出たら、接続先だけでなくマウント形態も確認する。

しろまえ殿の結論は、署名・応答・重い処理を一つの関数に詰め込まないことだ。 境界ごとに確認項目を分けると、失敗の場所が見える。