REST API асинхронность и интеграции

Асинхронные операции и Webhooks

📚 24 вопросовПройти тест →
Лекция

Асинхронные операции и Webhooks

REST API асинхронность и интеграции

Асинхронные операции и Webhooks

Введение: очередь в кафе и номерок ☕🔔

Представь: ты заказал сложный торт. Его не делают за 5 секунд, поэтому тебе дают номерок. Ты идёшь по своим делам, а когда торт готов — тебя зовут. Асинхронные операции в API работают так же: запрос приняли, работа идёт в фоне.
💡 Совет: если действие занимает больше пары секунд — делай его асинхронным. ✅ Вывод: асинхронность снимает ожидание и снижает ошибки от повторов.

Проблема → решение

Проблема: долгий запрос зависает, пользователь жмёт «обновить» и создаёт дубликаты. Решение: принять запрос, выдать Job ID и сообщить результат позже (polling или webhook).

Чем помогает и как работает

Асинхронная схема помогает не блокировать клиента и не перегружать сервер. Как это работает: клиент отправляет запрос → сервер возвращает Job ID → работа выполняется в фоне → клиент получает результат по статусу или webhook.

Ключевые термины (простыми словами)

  • Async (асинхронно) — результат приходит позже, а не сразу.
  • Job (задача) — единица работы в фоне.
  • Job ID — номер этой задачи.
  • Queue (очередь) — список задач, которые ждут выполнения.
  • Worker (воркер) — процесс, который выполняет задачи из очереди.
  • Polling (пуллинг) — когда клиент сам периодически спрашивает статус.
  • Webhook — когда сервер сам отправляет событие клиенту.
  • Event ID — уникальный номер события для защиты от дублей.
  • Signature (подпись) — защита webhook от подделки.

Самое важное (must‑know)

  • ✅ Асинхронный старт обычно возвращает 202 Accepted и Job ID.
  • ✅ Для клиента нужен endpoint статуса, где видно queued/processing/done/failed.
  • ✅ Webhook нельзя принимать «как есть» — нужна подпись/секрет.
  • ✅ Webhook может прийти дважды — нужен Event ID и дедупликация.
  • ✅ Долгие операции нельзя «держать» одним запросом.

1. Асинхронная операция + Job ID

Назначение: принять запрос и запустить работу в фоне. Простыми словами: сервер говорит «я начал, вот номер задачи». Аналогия: ты оставил номер телефона в сервисе и ждёшь звонка.
Пример:
POST /reports202 AcceptedLocation: /jobs/abc123 {  "jobId": "abc123"}
🔎 Как это происходит на практике:
  1. Клиент запускает выгрузку отчёта.
  2. Сервер создаёт задачу и возвращает Job ID.
  3. Клиент показывает «готовится» и ждёт результат.
Характеристики:
  • ✅ быстрый ответ (не ждём минуту);
  • ✅ есть Job ID для отслеживания;
  • ✅ работа идёт отдельно от запроса.
Когда использовать: отчёты, импорты, генерация файлов, массовые операции. ✅ Вывод: Job ID — это «номерок», который связывает клиента с задачей.

2. Статусы задачи (queued → processing → done/failed)

Назначение: показывать, на каком этапе находится работа. Простыми словами: это короткое «в очереди / делаем / готово / ошибка». Аналогия: табло в кафе: «принято», «готовится», «готово».
Пример:
GET /jobs/abc123200 OK {  "status": "processing",  "progress": 40}
🔎 Как это происходит на практике:
  1. Клиент спрашивает статус по Job ID.
  2. Сервер отдаёт текущее состояние.
  3. UI обновляет «готовится 40%».
Характеристики:
  • ✅ статусы фиксированы и документированы;
  • ✅ есть причина ошибки при failed;
  • ✅ прогресс опционален.
Когда использовать: всегда, если задача не мгновенная. ✅ Вывод: статус даёт пользователю понимание «что сейчас происходит».

3. Polling: периодическая проверка

Назначение: дать клиенту способ узнать результат без webhook. Простыми словами: клиент сам «заглядывает» каждые N секунд. Аналогия: ты проверяешь почтовый ящик, не ждёшь звонка.
Пример:
GET /jobs/abc123GET /jobs/abc123GET /jobs/abc123
🔎 Как это происходит на практике:
  1. Клиент ставит таймер (например, раз в 5–10 секунд).
  2. Сервер отвечает текущим статусом.
  3. Клиент прекращает запросы, когда статус done/failed.
Характеристики:
  • ✅ просто реализовать;
  • ⚠️ больше нагрузки на сервер;
  • ✅ работает, если webhook недоступен.
Когда использовать: простые проекты или когда клиент не принимает webhook. ✅ Вывод: polling — это проще, но дороже по нагрузке.

4. Webhook: сервер сам сообщает

Назначение: уведомлять клиента, когда всё готово. Простыми словами: сервер сам стучится и говорит «готово». Аналогия: курьер звонит, когда приехал.
Пример:
POST https://client.app/webhooks/report-readyContent-Type: application/json {  "event": "report.ready",  "jobId": "abc123"}
🔎 Как это происходит на практике:
  1. Клиент заранее даёт URL для webhook.
  2. Сервер завершает работу и отправляет событие.
  3. Клиент получает событие и обновляет статус.
Характеристики:
  • ✅ почти мгновенно;
  • ✅ меньше запросов от клиента;
  • ⚠️ нужен публичный endpoint.
Когда использовать: когда важна скорость и много задач. ✅ Вывод: webhook делает общение «сервер → клиент» быстрым и удобным.

5. Безопасность Webhook (подпись + Event ID)

Назначение: защитить webhook от подделки и дублей. Простыми словами: «проверь пароль» и «не принимай одно и то же дважды». Аналогия: курьер называет секретное слово и показывает номер заказа.
Пример:
POST /webhooks/report-readyX-Signature: sha256=8ab1...X-Event-Id: evt_123 { "event": "report.ready", "jobId": "abc123" }
🔎 Как это происходит на практике:
  1. Сервер подписывает тело и ставит X-Signature.
  2. Клиент пересчитывает подпись своим секретом.
  3. Если подпись не совпала — запрос игнорируется.
Характеристики:
  • ✅ подпись защищает от фейковых запросов;
  • ✅ Event ID спасает от дублей;
  • ✅ логика простая: «проверил → принял».
Когда использовать: всегда, если принимаете webhook извне. ✅ Вывод: подпись и Event ID — это минимальная безопасность и защита от повторов.

6. Очереди и воркеры (кто делает работу)

Назначение: выполнять тяжёлую работу отдельно от API. Простыми словами: API только принимает заказ, а работу делают воркеры. Аналогия: касса принимает заказ, кухня готовит.
Пример:
API -> Queue -> Worker -> обновление статуса
🔎 Как это происходит на практике:
  1. API кладёт задачу в очередь.
  2. Воркер забирает задачу и выполняет.
  3. Результат записывается в статус или отправляется webhook.
Характеристики:
  • ✅ снимает нагрузку с API;
  • ✅ задачи выполняются последовательно;
  • ✅ легко масштабировать воркеры.
Когда использовать: массовые операции, импорты, генерации. ✅ Вывод: очередь и воркер — это «двигатель» асинхронных задач.

Сравнение подходов

ПодходПлюсыМинусыКогда подходит
Синхронно (в ответе)простая логикадолгие ответы, таймаутыкороткие операции
Асинхронно (Job ID)нет ожидания, меньше таймаутовнужна доп. логикадолгие операции
Способ получения результатаПлюсыМинусыКогда подходит
Pollingлегко начатьмного запросовнебольшая нагрузка
Webhookбыстро, меньше запросовнужен публичный endpointбольшие системы

Часто спрашивают на собеседованиях

  • Почему для длинной операции возвращают 202, а не 200? ✅ Вывод: 202 означает «принято в работу», результат будет позже.
  • Чем polling отличается от webhook? ✅ Вывод: polling — клиент спрашивает сам, webhook — сервер сообщает сам.
  • Как защитить webhook? ✅ Вывод: проверять подпись и использовать секрет.
  • Что делать, если webhook пришёл дважды? ✅ Вывод: хранить Event ID и игнорировать дубликаты.
  • Как не создать дубли при повторном POST? ✅ Вывод: использовать Idempotency‑Key или проверять одинаковые запросы.

Типичные ошибки

Ошибка 1: держать долгий запрос до конца

❌ Неправильно: ответ приходит через минуту. ✅ Правильно: вернуть 202 и Job ID. Почему: иначе таймауты и дубли.

Ошибка 2: нет endpoint статуса

❌ Неправильно: клиент не знает, готово ли. ✅ Правильно: GET /jobs/{id} со статусом. Почему: пользователь должен видеть прогресс.

Ошибка 3: webhook без подписи

❌ Неправильно: принимать любые POST. ✅ Правильно: проверять X-Signature. Почему: иначе любой может подделать событие.

Ошибка 4: polling каждую секунду

❌ Неправильно: спамить сервер. ✅ Правильно: разумный интервал и backoff. Почему: это снижает нагрузку.

Ошибка 5: не обрабатывать дубликаты webhook

❌ Неправильно: каждое событие создаёт запись. ✅ Правильно: проверять Event ID. Почему: webhooks часто ретраятся.

Ошибка 6: смешивать фильтры и job id

❌ Неправильно: /jobs?id=123 ✅ Правильно: /jobs/123 Почему: Job ID — это ресурс, он в path.

Best Practices

  • Возвращайте 202 + Job ID для долгих операций.
  • Документируйте статусы и поля ответа.
  • Ограничивайте частоту polling (5–10 сек).
  • Используйте подпись и Event ID для webhook.
  • Делайте обработку webhook быстрой (200 OK сразу).
  • Логи и метрики по jobId помогают искать ошибки.

Заключение

Асинхронные операции спасают от таймаутов и дублей. Webhook делает уведомления быстрыми и удобными. ✅ Вывод: если работа долгая — делай её асинхронной и сообщай результат правильно.
🎯

Проверьте знания

Закрепите материал — пройдите тест по теме «Асинхронные операции и Webhooks»

Пройти тест →