한양과학기술고등학교

에듀테크 프로젝트 대시보드

웹훅 (Webhook)

웹훅(Webhook)은 "무슨 일이 생겼는지 계속 물어보는" 대신, 이벤트가 발생한 쪽이 미리 등록된 URL로 직접 결과를 밀어 넣어주는(push) 방식입니다. GitHub의 push 알림, 결제사(Stripe/토스)의 결제 완료 알림, 슬랙 알림 봇이 모두 웹훅으로 동작합니다. 아래에서 폴링(polling)과 웹훅의 차이를 직접 눈으로 비교해 보세요.
🔁 폴링 방식 GET /orders/1234 반복 호출
// "주문 이벤트 발생" 버튼을 눌러보세요
요청 횟수 0
이벤트 인지까지 걸린 시간 —
🔔 웹훅 방식 POST /webhooks/order 즉시 수신
// 이벤트 발생 시 콜백 URL로 즉시 전송됩니다
요청 횟수 0
이벤트 인지까지 걸린 시간 —
폴링은 다음 주기가 돌아올 때까지 이벤트를 모르고, 그동안 서버에 의미 없는 요청을 계속 날립니다. 웹훅은 이벤트가 발생한 그 순간 콜백 URL로 알려주므로 지연이 거의 없고 불필요한 요청도 없습니다. 대신 웹훅은 내 서버가 외부에서 접근 가능한 URL을 갖고 있어야 하고, 받은 요청이 진짜 발신자가 보낸 것인지 서명(signature)으로 검증해야 합니다 — 바로 아래에서 실습해봅니다.
✍️ HMAC-SHA256 서명 검증 실습
⚡ 웹훅 동작 흐름
① 이벤트 발생
→
② payload+서명 생성
↓
③ POST 콜백 URL
→
④ 서명 헤더 검증
↓
⑤ 200 OK 즉시 응답
→
⑥ 비동기로 실제 처리
재시도(Retry)와 멱등성(Idempotency): 응답이 늦거나 실패하면 발신 측은 지수 백오프로 같은 이벤트를 여러 번 재전송할 수 있습니다. 그래서 수신 서버는 payload의 event_id를 기록해두고 이미 처리한 이벤트면 다시 처리하지 않도록(멱등) 만들어야 합니다.
🌐 실전 사용 사례
GitHub — push, PR, 이슈 이벤트를
등록된 URL로 전송 (CI/CD 트리거)
결제사 (Stripe/토스) — 결제 성공/실패를
가맹점 서버에 실시간 통지
Slack Incoming Webhook — 특정 URL에
POST만 하면 채널에 메시지 게시

# FastAPI — 서명 검증 후 빠르게 응답 @app.post("/webhooks/order") async def receive_webhook(request: Request): body = await request.body() sig = request.headers.get("X-Webhook-Signature") expected = hmac.new(SECRET, body, hashlib.sha256).hexdigest() if not hmac.compare_digest(sig, expected): raise HTTPException(401) # event_id로 중복(재시도) 처리 방지 후 # 무거운 작업은 큐에 넘기고 즉시 응답 return {"received": True}