API-интеграции: почему соединить сервисы недостаточно

Интеграция должна быть наблюдаемой: события, статусы, логи, ошибки и восстановление.

Интеграцию обычно считают сделанной, когда данные дошли из одной системы в другую. На демонстрации это выглядит убедительно: заявка появилась в CRM, статус обновился, все довольны.

Проблемы начинаются позже и выглядят иначе. Данные дошли не все. Что-то пришло дважды. Внешний сервис ответил ошибкой, о которой никто не узнал. Через неделю выясняется расхождение, и восстановить, что именно произошло, невозможно — нет ни следов, ни статусов.

Что такое событие

Проектирование интеграции начинается не с эндпоинтов, а со списка бизнес-событий: клиент оставил заявку, оплата прошла, менеджер сменил статус, документ подписан. Событие — это то, что произошло в бизнесе, а не вызов метода.

Такой список полезен ещё до кода. По нему видно, какие системы вообще должны узнать о событии, что происходит, если одна из них недоступна, и какие события можно потерять без последствий, а какие нельзя ни при каких обстоятельствах.

У каждого события полезно сразу договориться о составе данных: что передаётся всегда, что может отсутствовать, что менять нельзя. Изменение формата через полгода — обычное дело, и переживёт его только та интеграция, где версия события указана явно, а принимающая сторона умеет игнорировать незнакомые поля.

Почему нужны статусы

Передача данных — не мгновенное действие, а процесс с состояниями. Сообщение принято, поставлено в очередь, отправлено, подтверждено, отклонено. Пока этих состояний нет, единственный доступный ответ на вопрос «дошло ли» — «вроде бы да».

  • у каждой передачи есть свой идентификатор
  • видно текущее состояние и время последней попытки
  • повторная отправка того же события не создаёт дубль
  • есть конечные состояния, а не только «в процессе»

Как работать с ошибками

Ошибки в интеграциях делятся на две неравные группы. Временные — сеть, таймаут, сервис на той стороне перегружен: их лечит повтор с растущей паузой. Постоянные — неверный формат, отсутствующее поле, отказ по правилам: повторять их бессмысленно, сколько ни пробуй.

Разделять их нужно на уровне кода, иначе система будет часами долбиться в стену и молчать о настоящей проблеме. Постоянные ошибки должны попадать туда, где их увидит человек, и оставаться в состоянии, из которого их можно перезапустить после исправления.

Повторы требуют одного условия, о котором часто забывают: принимающая сторона должна выдерживать повторную доставку одного и того же события. Иначе первая же неудачная попытка, которая на самом деле дошла, создаст дубль заявки или вторую оплату. Проверяется это просто — отправьте одно событие дважды и посмотрите, что получилось.

Полезно заранее решить, что делать с сообщениями, которые не удалось доставить совсем. Терять их нельзя, обрабатывать автоматически — тоже. Обычно их складывают в отдельную очередь, где они ждут человека: он смотрит причину, правит данные и запускает заново. Без такой очереди неудачные сообщения либо исчезают, либо навсегда застревают в повторах.

Логи и документация

Лог интеграции пишется не для разработчика, а для того, кто будет разбираться через полгода. Полезная запись отвечает на вопросы: какое событие, куда отправляли, что ответили, когда, какая попытка по счёту. Персональные данные в логи не кладут — там достаточно идентификатора.

Документация нужна примерно того же объёма: список событий, формат каждого, правила повторов, что считается ошибкой и к кому идти при сбое. Одна страница, написанная сразу, экономит недели через год, когда команда сменилась.

Отдельно стоит записать, что делать при типовых сбоях: как перезапустить зависшую передачу, как найти конкретную заявку по идентификатору, кому звонить, если внешний сервис отвечает ошибкой третий час. Это инструкция для дежурного, а не для разработчика, и написать её надо так, чтобы ей мог воспользоваться тот, кто интеграцию не писал.

Поддержка интеграции

Интеграция не бывает готовой навсегда. На той стороне меняются версии API, появляются новые обязательные поля, меняются правила. Поэтому у неё должен быть владелец и способ узнать о поломке раньше, чем о ней сообщит клиент.

Минимум — уведомление о накоплении ошибок и простой экран, где видно очередь и последние сбои. Этого достаточно, чтобы расхождение находили за час, а не через неделю по жалобе.

Полезна и регулярная сверка: раз в сутки сравнить количество записей на обеих сторонах и показать расхождение. Она ловит то, что не поймает ни один лог, — события, которые не отправились вовсе, потому что их никто не создал. Такие пропажи самые неприятные: со стороны интеграции всё выглядит идеально.

Системы связаны, но сбои находятся поздно?

Опишите, какие сервисы обмениваются данными и что происходит при ошибке. Мы разберём события, статусы, повторы и то, чего не хватает для наблюдаемости.

Показать процесс Aivex