Webhooks를 로컬에서 테스트하는 방법: 2026 완전 가이드
발행: (2026년 2월 26일 오후 03:07 GMT+9)
5 분 소요
원문: Dev.to
Source: Dev.to
소개
로컬 개발 중에 웹훅을 테스트하는 것은 로컬호스트가 인터넷에서 접근할 수 없기 때문에 까다롭습니다. Stripe, GitHub, Shopify와 같은 서비스는 웹훅 엔드포인트에 HTTP POST 요청을 전달하기 위해 공개 URL이 필요합니다.
터널링 도구
ngrok
ngrok http 3000
https://abc123.ngrok.io와 같은 공개 URL을 생성하고localhost:3000으로 포워딩합니다.- 무료 티어 URL은 재시작할 때마다 변경되며, 유료 플랜($8‑25/월)은 안정적인 URL을 제공합니다.
Cloudflare Tunnel (formerly Argo Tunnel)
cloudflared tunnel --url http://localhost:3000
- 무료이며 기존 Cloudflare 설정과 통합됩니다.
localtunnel
npx localtunnel --port 3000
- 오픈소스 대안이며, 신뢰성은 상황에 따라 다를 수 있습니다.
캡처 서비스
캡처 서비스는 들어오는 웹훅을 위한 인박스로 동작하여 나중에 검사, 저장 및 재생할 수 있게 해줍니다.
- Permanent URL – 예:
https://thunderhooks.com/h/my-project.
워크플로우
- 제공자(Stripe, GitHub 등)를 영구 URL로 웹훅을 전송하도록 설정합니다.
- 웹훅이 저장됩니다(보통 7‑30일 보관) 그리고 대시보드에서 확인할 수 있습니다.
- 준비가 되면 캡처된 웹훅을 로컬 터널 URL로 재생합니다.
직접 터널링 대비 장점
- 24시간 터널을 유지할 필요가 없으며, 놓친 전달은 큐에 저장됩니다.
- 디버깅을 위해 동일한 페이로드를 여러 번 쉽게 재생할 수 있습니다.
- 제공자 설정에서 URL을 계속 업데이트할 필요가 없습니다.
트레이드오프
- 직접 포워딩이 아니라 캡처 → 재생이라는 두 단계 프로세스이지만, 유연성 때문에 충분히 가치가 있습니다.
제공자 별 테스트 도구
Stripe CLI
stripe listen --forward-to localhost:3000/webhooks/stripe
stripe trigger payment_intent.succeeded
- 실시간 Stripe 이벤트를 로컬 서버로 포워딩합니다.
- 필요에 따라 테스트 이벤트를 트리거할 수 있습니다.
- Stripe에만 적용됩니다.
GitHub
- 내장 포워딩 기능은 없지만, 설정 페이지에서 GitHub API를 사용해 웹훅을 재전송할 수 있습니다.
권장 워크플로우
| 시나리오 | 추천 도구 |
|---|---|
| 빠른 디버깅 및 검사 | 캡처 서비스 |
| 통합 테스트 (특정 이벤트) | 제공자 CLI (예: Stripe CLI) |
| 실제 이벤트를 사용한 엔드‑투‑엔드 테스트 | 안정적인 터널 (ngrok 유료 플랜, Cloudflare Tunnel) |
개발 모범 사례
- Signature verification – 개발 단계에서 절대 생략하지 말고, 프로덕션 전에 반드시 활성화하세요. Stripe의 서명 검증 문서를 참고하세요.
- Environment variables – 환경별(로컬, 스테이징, 프로덕션) 웹훅 URL을 변수로 관리하세요.
- Idempotency – 웹훅은 여러 번 전달될 수 있으므로, 핸들러가 중복을 정상적으로 처리하도록 구현하세요. 동일한 웹훅을 재생해 테스트합니다.
- Timeout handling –
2xx상태 코드를 빠르게(30초 이내) 반환하고, 무거운 처리는 백그라운드 작업으로 넘깁니다.
배포 전 체크리스트
- 핸들러가
2xx상태 코드를 즉시 반환한다 - 서명 검증이 활성화되어 있다
- 중복 전달이 올바르게 처리된다(멱등성)
- 실패가 충분한 컨텍스트와 함께 로그에 기록된다
- 일시적인 실패에 대한 재시도 로직이 구현되어 있다
- 타임아웃 처리가 정상적으로 동작한다