04Архитектура
Дизайн webhooks: payload, подпись, retry, идемпотентность
Полный дизайн исходящих webhooks: схема payload, HMAC-подпись, политика ретраев, идемпотентность, защита от replay, observability, dead letter, юзер-debug.
Действуй как senior backend архитектор. Спроектируй исходящие webhooks для событий {{event_types}}. Стек: {{stack}}, объём: {{scale}} events/day.
Что должно быть в дизайне
1. Payload schema
- Стабильная версия (
v1) в URL или заголовкеX-Webhook-Version. Никаких breaking changes безv2. - Обязательные поля:
id(UUID события),type(e.g.order.created),created_at(ISO 8601 UTC),data(объект). api_versionотдельно отdataschema version.data— snapshot на момент события, не "текущее состояние". Webhook доехал через час — у нас в БД уже могло измениться.- Размер payload — фикс ≤ 256KB. Большие объекты —
{ "object_url": "https://api/...?id=X" }чтобы получатель забрал сам.
2. HMAC signing
- Алгоритм: HMAC-SHA256.
- Заголовки:
X-Webhook-Signature: t=<timestamp>,v1=<hex>(Stripe-style — позволяет ротацию схем). - Подписываемая строка:
{timestamp}.{raw_body}.timestampв заголовке защищает от replay. - Secret per endpoint, ротация — два активных secret'а одновременно (overlap window 24-48 часов).
- В docs дать готовый verify-snippet на 3-4 языках (Node, Python, Go, Ruby).
3. Retry policy
- Exponential backoff с jitter:
1m → 5m → 30m → 2h → 6h → 24h, max 6 attempts, итого ~32 часа. - Retry только на: network error, timeout, HTTP 5xx, HTTP 429.
- 4xx (кроме 429) — не retry, помечаем как permanently failed, в dead letter.
- 2xx (любой) — success.
- Timeout на одну попытку — 10 секунд (а не 30: медленный consumer не должен блокировать твою очередь).
4. Idempotency на стороне получателя
X-Webhook-Id: <uuid>уникален per delivery attempt. У одного события — один id, повторные попытки несут тот же id.- В docs явно: "consumer должен дедуплицировать по
id(хранить минимум 7 дней)". - На стороне sender — exactly-once delivery невозможно; обеспечиваем at-least-once + id для idempotency.
5. Replay protection
- Timestamp в подписи + строгая валидация: ±5 минут от
now(). Старше — отбрасывать (это уже не webhook, это атака). - Документировать: получатель обязан проверять timestamp, не только подпись.
6. Observability
- Per-endpoint метрики:
delivery_attempts,success_rate,p50/p95/p99 latency,failure_rate by status_code. - UI для юзера (dashboard эндпоинта): список последних 100 deliveries с raw request/response, status, retry count, next retry time.
- Алерт получателю (email/in-app), если success rate за 24h < 80% — "что-то у вас сломалось".
7. Dead letter / failure handling
- После 6 failed attempts → DLQ + статус endpoint'а
disabledесли 100 DLQ подряд. - Юзер может вручную replay конкретное событие из UI или через API:
POST /webhooks/events/{id}/redeliver. - DLQ хранится 30 дней, потом purge.
8. User-debug experience
- В UI: текущий status подписи (signing secret последней ротации), пример verify-кода на их языке.
- "Test endpoint" кнопка — отправляет synthetic event
webhook.testс известным payload, юзер видит full request/response inline. - При неуспехе показать не "Failed" а конкретно:
HTTP 401 / timeout after 10s / TLS handshake failed: <reason>.
Формат вывода
## Payload schema
```json
{ ... пример ... }
Signature spec
<алгоритм + пример заголовков>
Retry table
| Attempt | Delay | Timeout | | 1 | 0 | 10s | ...
API surface
- POST /webhooks/endpoints (create)
- GET /webhooks/endpoints/{id}/deliveries (list)
- POST /webhooks/events/{id}/redeliver ...
Receiver pseudocode (3 языка)
## Anti-patterns
- ❌ Подписывать не raw body, а распарсенный JSON — receiver не воспроизведёт байты (whitespace, key ordering) → подпись не сойдётся.
- ❌ Retry на 4xx — DDoS получателя, который вернул "не надо мне это".
- ❌ Timeout 60s на доставку — медленный consumer кладёт весь queue.
- ❌ Без timestamp в подписи → replay-атака навсегда валидна.
- ❌ Менять payload без версии → у всех existing consumers ломается parsing.
- ❌ "Exactly once" обещание → невыполнимо, лучше честно at-least-once + id для дедупликации.
- ❌ Без UI для debug → саппорт-тикеты "почему не пришло" забивают inbox.
- ❌ Без dead letter → потерянные события невозможно восстановить.
Похожие промты
agents / orchestration
Multi-agent: координатор и специалисты
Архитектура из координатора и специализированных агентов: передача контекста, дедупликация, race conditions.
agentsorchestrationmulti-agent
Открыть
Продвинутый30-60 мин
agents / create
Новый subagent или новый skill: что выбрать
Decision tree: создавать ли отдельного агента или достаточно skill. Критерии — контекст, переиспользование, frequency, complexity.
agentsskillsarchitecture
Открыть
Начальный15-30 мин
code / architecture
Architecture Decision Record (ADR)
Зафиксировать архитектурное решение: контекст, варианты, выбор и trade-offs.
architectureadrdocumentation
Открыть
Средний30-60 мин