Большинство проблем, которые обнаруживаются спустя месяцы, начинаются с неясных договорённостей при первом разговоре. Часто участники даже не замечают, что уже принимают технические решения. Никто не записал, какая система владеет адресом электронной почты клиента, и теперь так считают обе. Они обновляют его в противоположных направлениях, когда сотрудник поддержки забывает, на каком экране находится.
Бриф на API-интеграцию (на странице услуги я называю его контрактом данных) это короткий документ, который не даёт такому случиться. Его пишут до начала разработки, и он отвечает на один простой вопрос: что именно мы договорились строить?
Если способ реализации ещё не выбран, перед брифом я сравниваю покупку, интеграцию и разработку внутреннего инструмента.
Что включить в бриф на API-интеграцию?
Для каждого передаваемого поля укажите, какая система хранит верное значение. Направление и частоту передачи. Ключ идемпотентности, который определяет, что такое дубликат. Ответственных за авторизацию и обработку ошибок. Критерии приёмки, достаточно конкретные, чтобы проверить их без уточнений. Вот и весь список.
Шаблон рассчитан на то, чтобы уместить эти решения на одной-двух страницах и согласовать их до начала разработки.
Цель процесса и задействованные системы
Бриф нужен, чтобы ответить на более узкий вопрос, чем «соединить систему A с системой B». Двум и более системам редко нужно всё, что есть у других. Обычно одной системе нужны несколько полей из другой: по триггеру и чаще всего в одну сторону.
Поэтому первый раздел брифа просто называет системы и задачу обычными словами: какие две (или больше) системы участвуют, что запускает обмен и какой результат считать завершённым обменом. Клиент регистрируется, срабатывает вебхук, сотруднику поддержки нужно увидеть статус доставки, для получения которого нужно пройти ещё две системы. Или любой другой настоящий триггер. Раздел намеренно короткий. Его задача: не дать запросу незаметно вырасти в общий проект «соединить всё со всем». Именно оттуда берутся и стоимость, и дублирование.
Для гипотетического случая «CRM и система выставления счетов», который я использую ниже, раздел заполняется так: Системы: CRM и система выставления счетов. Триггер: выставлен счёт или изменился платёжный адрес. Готово: другая система один раз получила новое значение.
Источник истины и поля
Для каждого поля, которое будет передаваться между системами, бриф указывает, кто им владеет. При расхождении данных верным считают значение системы-владельца. Удобство чтения из другой системы этого не меняет.
Гипотетический пример: допустим, и в CRM, и в системе выставления счетов хранится платёжный адрес клиента. Если менеджер по продажам исправляет адрес в CRM после звонка, то полем владеет CRM, хотя адрес нужен системе выставления счетов, чтобы напечатать счёт. Строка в брифе «Платёжным адресом владеет CRM, система выставления счетов его получает» сразу устраняет спор, который иначе всплыл бы при первом же расхождении.
У каждого поля есть также направление (какая система пишет, какая читает) и периодичность (в реальном времени по событию, опросом по расписанию или пакетом за ночь). Двусторонняя синхронизация почти всегда состоит из нескольких односторонних потоков, идущих по одному каналу. Если назвать их по отдельности, то добросовестная просьба «синхронизировать всё» не превратится в две системы, которые перезаписывают друг друга.
Вот заполненный пример для случая «CRM и система выставления счетов»:
Сравнительная таблица: прокрутите вбок, чтобы увидеть все столбцы
| Поле | Владелец (источник истины) | Направление | Периодичность | Ключ идемпотентности |
|---|---|---|---|---|
| Платёжный адрес клиента | CRM | CRM → система выставления счетов | При изменении (вебхук) | ID клиента + версия адреса |
| Сумма счёта и позиции | Система выставления счетов | Система выставления счетов → CRM | При выставлении (вебхук) | ID счёта |
| Статус оплаты | Система выставления счетов | Система выставления счетов → CRM | Каждые 30 минут (опрос) | ID счёта + время статуса |
Ключ идемпотентности чаще всего пропускают в черновиках, а он предотвращает самый частый сбой: одно и то же событие приходит дважды и обрабатывается дважды. Он не обязан быть сложным, часто хватает ID счёта. Но его нужно записать до начала разработки, а не выяснять после того, как в чьём-то почтовом ящике появится дубль счёта.
Авторизация, ошибки и ответственность
В брифе также должно быть сказано, что происходит, когда что-то идёт не так, потому что интеграция не готова, если работает только без сбоев.
Авторизация: кто владеет учётными данными с каждой стороны, где они хранятся и кто может их отозвать, если интеграцию нужно срочно отключить. Ошибки: три отдельных вопроса. Что считается сбоем, который можно повторить, а что постоянным. Куда попадает запуск, когда повторные попытки закончились (очередь dead-letter, которую проверяет ответственный человек, а не непрочитанная строка в журнале). И кого уведомляют, когда это случилось. «Письмо разработчику» вполне годный ответ, если он записан. Обычно беда в том, что никто ничего не решил, а не в том, что выбрали не того человека.
Для случая «CRM и система выставления счетов» заполнено так: Учётные данные: по одному API-ключу с каждой стороны, хранит руководитель операций в корпоративном менеджере паролей, отозвать может любая сторона. Можно повторить: тайм-ауты и ответы 5xx, повторяются до согласованного предела. Постоянная ошибка: 4xx для неизвестного ID клиента. Путь dead-letter: таблица неудавшихся запусков в собственной базе интеграции. Кого уведомляют: руководителя операций, письмом, при каждом запуске, попавшем в dead-letter.
Конкретный пример есть в публичной документации. В документации Shopify по вебхукам прямо сказано, что доставка «не всегда гарантирована», и рекомендованы две вещи, которые должен сделать получатель. Первая: игнорировать повторные доставки, проверяя заголовок X-Shopify-Webhook-Id в каждом событии. Вторая: запускать периодическую сверку, которая забирает данные через API Shopify, чтобы принимающая система не зависела только от вебхуков. Оба требования существенны: именно ради них и существуют ключ идемпотентности и путь dead-letter, для этого API и для большинства других, которые отправляют вебхуки.
Критерии приёмки
Последнее, что фиксирует бриф: какой результат считать готовым. Условия должна уметь проверить третья сторона без уточнений. Короткий пример, снова для случая «CRM и система выставления счетов»:
- Каждый счёт, выставленный в системе выставления счетов, появляется у соответствующего клиента в CRM в течение согласованного интервала.
- Вебхук, доставленный дважды для одного и того же ID счёта, даёт ровно одну запись, а не две.
- Изменение платёжного адреса в CRM отражается в следующем счёте, который система выставления счетов выставит этому клиенту.
- Неудавшаяся доставка, исчерпавшая повторные попытки, появляется в журнале dead-letter с ID счёта и вызывает оповещение назначенному человеку. Одной записи в журнале недостаточно.
- Откат интеграции (отключение вебхука, возврат к ручному процессу) занимает один описанный шаг и не требует правок кода.
Каждый пункт называет факт, который можно пойти и проверить (число, запись, строку журнала), а не ощущение, что пайплайн «работает правильно».
Выполненную матрицу проверок на дубликаты, неверный порядок доставки, тайм-ауты и восстановление смотрите в приёмочных тестах повторных попыток интеграции.
Что бриф не решает
Бриф намеренно узкий. Он не задаёт цену и сроки: они появляются, когда описанный выше объём достаточно конкретен для сметы.
Он не выбирает, какой из нескольких подходов к интеграции использовать (вебхук, опрос или выгрузку по расписанию) сверх того, что уже следует из строки периодичности в таблице. Этот выбор обычно зависит от ограничений, которые в бриф не попадают, например от лимитов запросов или существующего планировщика задач. И о вашем трекинге и аналитике в нём ничего нет: синхронизация CRM со счетами и событие покупки в GA4 это несвязанные вопросы, и этот документ второго не касается.
Заполненный пример и пустой шаблон
Таблица и список приёмки выше это один заполненный пример для двух гипотетических систем, CRM и системы выставления счетов. Пример не содержит данных клиентского внедрения. Единственное реальное поведение платформы, упомянутое в этом гайде, это поведение Shopify, и только так, как его описывает публичная документация.
В пустом шаблоне (Markdown, скачать) те же разделы и та же таблица, но строки пустые. Заполнить его для своих систем можно до того, как с кем-то обсуждать разработку. Если хотите составить его вместе, это относится к API-интеграциям и автоматизации, а все услуги перечислены в списке услуг. Коротко о том, как я подхожу к такой работе, написано на странице «Обо мне».
Если сначала хотите всё обсудить, напишите мне: какие системы задействованы и что сегодня не работает.