API-интеграция связывает системы, которые развиваются независимо и могут временно работать с ошибками. Поэтому задача не сводится к одному успешному запросу. Надёжная интеграция должна переживать повторы, задержки, изменение схемы и частичную недоступность без потери или бесконтрольного дублирования данных.
Опишите данные и владельцев
Начните не с документации API, а с карты данных. Для каждого объекта укажите:
- где он создаётся;
- какая система назначает идентификатор;
- какие поля обязательны;
- кто имеет право изменять каждое поле;
- куда и с какой задержкой передаётся изменение;
- как распознать одну и ту же запись в разных системах;
- сколько времени должна храниться история.
Например, контакт может создаваться на сайте, дополняться менеджером в CRM и получать статус оплаты из учётной системы. Если обе системы свободно меняют одно поле, рано или поздно более старое значение перезапишет новое.
Назначьте источник истины
Для каждого типа данных должна существовать система, где значение считается главным. Это правило может различаться по полям: CRM владеет ответственным менеджером, каталог — ценой, платёжная система — фактом оплаты.
Зафиксируйте направление обмена:
- односторонняя передача;
- двусторонняя синхронизация с правилами конфликта;
- периодическая сверка;
- событие в реальном времени и контрольный пакет позже.
Двусторонняя синхронизация сложнее, чем кажется. Если она не обязательна, безопаснее выбрать одного владельца и запретить редактирование копии во второй системе.
Выберите способ запуска обмена
Основные варианты — webhook, периодический опрос и пакетная выгрузка.
Webhook быстро сообщает об изменении, но может прийти повторно, с задержкой или не дойти. Отправитель не всегда гарантирует порядок событий.
Периодический опрос проще контролировать, но создаёт задержку и дополнительную нагрузку. Он полезен как резервная сверка даже при наличии webhook.
Пакетная выгрузка подходит для больших объёмов и некритичной задержки, но требует контроля границ периода и частично обработанных файлов.
Нередко используется комбинация: webhook запускает быструю обработку, а ежедневная сверка находит пропущенные изменения.
Сделайте операции идемпотентными
Идемпотентность означает, что повтор одного события не создаёт новый результат. Это основа защиты от дублей.
Каждому входящему событию нужен стабильный ключ: идентификатор события поставщика или комбинация объекта, версии и типа операции. Перед обработкой система проверяет, выполняла ли она это действие ранее.
Недостаточно искать дубль по email или названию: реальные сущности могут иметь одинаковые значения, а данные — меняться. Правила сопоставления должны быть формальными и проверяемыми.
Обрабатывайте ошибки по типам
Не все ошибки следует повторять одинаково.
- Временные: таймаут, ответ 429 или 503. Повторяются с растущей задержкой.
- Ошибка данных: отсутствует обязательное поле или неверный формат. Требует исправления источника или ручного решения.
- Ошибка доступа: истёк токен или изменились права. Нужен сигнал ответственному.
- Конфликт: версия объекта устарела. Нельзя просто перезаписать более новое значение.
- Неизвестная: сохраняется с контекстом и останавливает конкретную операцию, а не весь поток.
После исчерпания повторов событие должно попасть в отдельную очередь или список восстановления. Бесконечный автоматический повтор скрывает проблему и создаёт нагрузку.
Сохраняйте связь идентификаторов
Один клиент может иметь ID 1842 в CRM и c_91aa в сервисе рассылок. Таблица соответствий должна храниться явно. Поиск по имени, телефону или email допустим только как контролируемый этап первичного сопоставления.
Если объект удалён или объединён, связь тоже должна получить статус. Иначе следующая синхронизация может создать удалённую запись заново.
Добавьте наблюдаемость
Журнал интеграции должен отвечать на вопросы:
- Что произошло и когда?
- Какой объект участвовал в операции?
- Откуда пришло событие и куда направлялось?
- Сколько было попыток?
- Каков текущий статус и что требуется для восстановления?
Полезны счётчики успешных и ошибочных операций, размер очереди, возраст самого старого события и время обработки. Персональные данные, токены и полные тела запросов без необходимости в журнал не помещаются.
Защитите данные и доступы
Интеграции часто получают больше прав, чем пользовательский интерфейс. Следуйте принципу минимальных привилегий: отдельная учётная запись, доступ только к нужным операциям и среде, регулярная смена секретов.
Проверяйте подпись webhook, ограничивайте размер входящих данных, валидируйте схему и не доверяйте имени файла или переданному URL. Для критичных действий сохраняйте аудит: кто и на основании какого события изменил запись.
Проверьте сценарии до запуска
Одного теста «запись успешно передалась» недостаточно. Проверьте:
- пустое и слишком длинное обязательное поле;
- повтор одного события;
- события, пришедшие не по порядку;
- таймаут после того, как удалённая система уже выполнила действие;
- ограничение частоты API;
- истёкший токен;
- частичную недоступность одной системы;
- изменение или удаление объекта во время обработки;
- восстановление события из ошибочной очереди;
- сверку после пропущенного периода.
Особенно важен таймаут после успешного действия. Клиент не получил ответ и считает запрос неудачным, хотя удалённая система уже создала запись. Без ключа идемпотентности повтор создаст дубль.
Подготовьте эксплуатацию
До запуска назначьте ответственного за уведомления и опишите процедуру восстановления. Она должна быть понятна не только разработчику: где увидеть ошибку, какие данные безопасно исправить, как повторить одну операцию и как проверить итог.
Надёжность интеграции определяется не отсутствием сбоев, а управляемым поведением при сбое. Если проблему можно быстро обнаружить, локализовать и восстановить без ручного сравнения тысяч записей, архитектура выполняет свою задачу.