194. 웹훅 (Webhook) 방식 통합

⚠️ 이 문서는 클라이언트가 "데이터 바뀐 거 있어?"라고 서버를 1초마다 귀찮게 찌르는 전통적인 폴링(Polling) 방식의 낭비를 없애기 위해, **서버 쪽에 "이벤트가 발생하면 내 URL 주소로 네가 직접 찔러줘!"라고 연락처를 남겨두어 서버가 클라이언트로 데이터를 밀어내는(Push) 역방향 API 호출(User-defined HTTP Callback) 기술인 '웹훅(Webhook)'**을 다룹니다.

핵심 인사이트 (3줄 요약)

  1. 본질: 전화를 내가 거는 것(API 호출)이 아니라, "일 끝나면 내 번호로 전화 줘"라고 콜백(Callback) 번호를 남기는 역발상 통신 구조다. (Reverse API라고도 불림)
  2. 가치: 1시간 동안 아무 일도 안 일어났는데 "새로운 결제 들어왔어?"라고 DB를 3,600번 두드리는 무의미한 네트워크/서버 부하를 0으로 만들고, 결제가 터지는 그 순간 0.1초 만에 즉각적으로 알림을 받을 수 있는 실시간(Real-time) 통합을 구현한다.
  3. 기술 체계: 슬랙(Slack), 깃허브(GitHub), 토스페이먼츠(결제 연동) 등 SaaS 생태계 통합의 심장이며, 수신 측은 웹훅을 받을 수 있는 열려있는 HTTP(S) 엔드포인트를 하나 파놓고 기다리면 끝난다.

Ⅰ. 폴링(Polling)의 비효율과 웹훅의 탄생

택배 기사에게 언제 오냐고 1분마다 전화하는 것은 미련한 짓이다.

  1. 전통적 API 통신 (Polling의 낭비):
    • 내 앱이 '토스페이먼츠'에 결제를 붙였다. 고객이 결제를 끝냈는지 확인하려면, 내 서버는 토스 서버에 GET /status API를 1초에 한 번씩 날려야 한다.
    • 고객이 카드를 꺼내 결제를 완료하는 30초 동안 내 서버는 30번을 찔렀고 29번은 "아직 결제 안 됨"이라는 쓰레기 응답을 받으며 서버 CPU를 낭비했다.
  2. 웹훅 (Webhook)의 동작 원리:
    • 내 서버(수신자)에 미리 /webhook/toss-payment-success 라는 API 주소(엔드포인트)를 파놓는다.
    • 토스(발신자) 개발자 센터에 들어가서 "결제가 완료되면 저 URL로 POST 요청 좀 날려주세요"라고 등록한다.
    • 내 서버는 아무 일도 안 하고 조용히 기다리다가, 고객 결제가 끝난 순간 토스 서버가 내 서버의 저 URL을 쾅! 하고 때려주며(Push) 결제 완료 JSON 데이터를 밀어 넣는다.

📢 섹션 요약 비유: 배달 앱(서버)을 켜고 "내 치킨 출발했나?"를 1분마다 새로고침(Polling)하며 쳐다보는 낭비 대신, "치킨 출발하면 내 카톡으로 메시지 보내(Webhook)"라고 알림 설정을 해두고 나는 맘 편히 다른 일을 하는 스마트한 비동기 통신 방식입니다.


Ⅱ. 대표적인 웹훅 연동 아키텍처 사례 (SaaS 생태계)

오늘날 대부분의 B2B 소프트웨어 통합은 웹훅으로 돌아간다.

  1. GitHub과 CI/CD 봇의 만남:
    • 개발자가 깃허브에 코드를 푸시(Push)했다.
    • 깃허브에 세팅된 웹훅이 발동하여 사내 젠킨스(Jenkins) 서버의 특정 URL을 찌른다. 젠킨스는 잠자고 있다가 그 찌름을 맞고 일어나 코드를 다운받아 빌드를 시작한다.
  2. 결제 모듈 (PG사 연동):
    • 고객이 화면에서 결제를 마쳤다. 사용자가 브라우저 창을 닫아버려도 결제는 완료 처리되어야 한다.
    • PG사(KG이니시스 등) 서버가 내 백엔드 서버의 웹훅 URL로 {"status": "DONE", "amount": 50000} 데이터를 쏴주어, 내 DB에 영수증이 확실히 찍히도록(비동기 승인) 보장한다.
  3. Slack(슬랙) 알림 연동:
    • 서버에 에러가 터지거나(Datadog), 회사 메일로 고객 불만이 들어오면, 슬랙이 열어둔 웹훅 URL(https://hooks.slack.com/services/T000...)로 데이터를 POST 쏴주면 사내 메신저 채팅방에 에러 메시지가 짠! 하고 예쁘게 출력된다.

📢 섹션 요약 비유: 웹훅은 전 세계 소프트웨어들이 서로 대화하는 범용 '삐삐(호출기)'입니다. 깃허브가 젠킨스에게 삐삐를 치고, 결제 서버가 우리 서버에 삐삐를 치고, 우리 서버가 슬랙에 삐삐를 치면서, 서로 복잡하게 코드를 얽지 않아도 연락처(URL) 하나만으로 거대한 자동화 컨베이어 벨트가 착착 돌아가는 마법입니다.


Ⅲ. 웹훅 도입 시 반드시 고려할 보안 및 트레이드오프

문을 열어놓고 기다리는 방식이라 가짜 손님(해커)과 폭우에 취약하다.

  1. 신뢰성 보장과 시그니처 (HMAC):
    • 내 결제 완료 웹훅 URL을 해커가 알아내서, 가짜로 결제 완료 메시지를 쏴주면 어떻게 될까? (치명적 보안 사고)
    • 이를 막기 위해, 토스 서버는 웹훅을 보낼 때 "나 토스 맞음"이라는 암호화된 서명(HMAC Signature)을 HTTP 헤더에 같이 담아 보낸다. 내 서버는 이 서명을 검증해서 토스가 보낸 게 맞을 때만 물건을 발송해야 한다.
  2. 수신 서버의 과부하 (Thundering Herd):
    • 내가 만든 이벤트 서버가 히트를 쳐서 1초에 10만 명이 동시에 신청 버튼을 눌렀다.
    • 파트너사 서버가 내 서버의 웹훅 URL을 1초에 10만 번 때리게 된다(DDoS 공격이나 다름없음). 수신 측은 이 웹훅 폭우를 버텨낼 수 있도록 앞단에 카프카(Kafka) 같은 큐(Queue)나 AWS API Gateway를 두어 트래픽을 임시로 담아내는 완충 지대를 설계해야 한다.
  3. 재시도(Retry)와 중복(Idempotency):
    • 내 서버가 잠깐 멈춰서 토스의 웹훅을 못 받았다면? 발신자는 내 서버가 200 OK를 뱉을 때까지 몇 번이고 웹훅을 재시도(Retry)하도록 설계되어야 한다.
    • 이때 내 서버가 1번 주문 건을 2번 중복으로 처리하지 않도록 멱등성(Idempotency, 1번을 여러 번 받아도 1번만 처리)을 띠게 쿼리를 짜야 한다.

📢 섹션 요약 비유: 문을 열어놓고 친구(웹훅)를 기다릴 때는 3가지를 조심해야 합니다. 친구 목소리를 흉내 내는 강도를 막기 위한 암호(시그니처 검증), 친구가 10만 명 동시에 뛰어 들어와 집이 무너지는 것을 막는 대기표(큐), 친구가 귀가 먹어 팩스를 두 번 보냈을 때 장부에 두 번 적지 않는 눈치(멱등성)가 반드시 필요합니다.