Webhook Event Dispatcher
Difficulty: Medium · Topics: Events, API, HTTP, Retry
Difficulty: Medium | Tags: API, Events, HTTP, Retry
Description
Implement a webhook dispatcher that sends HTTP POST requests to registered webhook URLs when events occur. Support retry on failure, payload signing for security, and event filtering.
Implement:
WebhookDispatcher
register(url, secret, eventTypes[]) — register a webhook endpoint
unregister(url) — remove webhook
dispatch(eventType, payload) — send event to all matching webhooks
getDeliveryStatus(deliveryId) → Status — check delivery status
Examples
Example 1 — Register and dispatch:
dispatcher = new WebhookDispatcher()
dispatcher.register(
url = "https://partner.com/webhook",
secret = "whsec_abc123",
events = ["order.created", "order.updated"]
)
dispatcher.dispatch("order.created", {
orderId: "ORD-001",
total: 99.99,
customer: "Alice"
})
// Sends POST to https://partner.com/webhook:
// Headers:
// Content-Type: application/json
// X-Webhook-Signature: sha256=<HMAC(payload, secret)>
// X-Webhook-Event: order.created
// X-Webhook-Delivery: <unique-delivery-id>
// Body: {"orderId": "ORD-001", "total": 99.99, "customer": "Alice"}
Example 2 — Event filtering:
// Webhook registered for ["order.created"] only
dispatcher.dispatch("order.deleted", {...}) // NOT sent to this webhook
dispatcher.dispatch("order.created", {...}) // Sent
Example 3 — Retry on failure:
// POST to webhook URL fails with 500:
// Retry 1: after 1 second
// Retry 2: after 2 seconds
// Retry 3: after 4 seconds
// After 3 failures → mark as failed, log for manual review
Constraints
- Payload signed with HMAC-SHA256 using the webhook's secret.
- Retry up to 3 times with exponential backoff on 5xx errors.
- Do NOT retry on 4xx errors (client error = bad config).
- Delivery timeout: 10 seconds per attempt.
- Event type supports wildcard
*(receive all events). - Must be async —
dispatch()should not block the caller.
Hints
Hint 1
Use a thread pool or async queue for non-blocking dispatch. Each registered webhook is checked for event type match before sending.