
Webhook웹훅
웹훅(Webhook)은 특정 이벤트 발생 시 서버가 미리 등록된 URL로 HTTP POST 요청을 자동 전송하는 이벤트 기반 통합 방식이다. 폴링 없이 실시간 이벤트를 수신할 수 있어 결제, 배포, 알림 등에 광범위하게 사용된다.
동작 원리
1. 수신 서버: 웹훅 URL 등록 (예: GitHub 저장소 설정)
2. 이벤트 발생 (예: PR 병합)
3. 이벤트 소스 서버: 등록된 URL로 POST 요청
4. 수신 서버: 페이로드 처리
"Reverse API" — API는 내가 당기는 것, 웹훅은 상대가 미는 것웹훅 수신 서버
javascript
const express = require('express');
const crypto = require('crypto');
app.post('/webhook/github', express.raw({ type: 'application/json' }), (req, res) => {
// 1. 서명 검증 (HMAC-SHA256)
const signature = req.headers['x-hub-signature-256'];
const hmac = crypto.createHmac('sha256', process.env.WEBHOOK_SECRET);
const digest = 'sha256=' + hmac.update(req.body).digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(digest))) {
return res.status(401).send('Invalid signature');
}
// 2. 즉시 200 응답 (타임아웃 방지)
res.status(200).send('OK');
// 3. 비동기 처리
const payload = JSON.parse(req.body);
const event = req.headers['x-github-event'];
if (event === 'push') {
triggerDeploy(payload.repository.name, payload.after);
}
});웹훅 신뢰성 확보
javascript
// 멱등성 처리 (중복 수신 방지)
const processedEvents = new Set();
app.post('/webhook', async (req, res) => {
const deliveryId = req.headers['x-github-delivery'];
if (processedEvents.has(deliveryId)) {
return res.status(200).send('Already processed');
}
processedEvents.add(deliveryId);
res.status(200).send('OK');
// 실패 시 재시도: 큐에 추가
await queue.add('webhook', { event: req.body });
});