Руководство · deployment
Как зависеть от API, который вы не контролируете
Вторая половина интеграции — чужой продукт: он меняется, истекает и падает по своему расписанию. Как собрать коннектор, который деградирует, а не портит данные, и узнаёт о поломке раньше клиентов.
Половина интеграции, которой в вашей команде никто не владеет
У интеграции две половины, и вы пишете только одну. Вторая — чужой продукт со своей дорожной картой, своими авариями, своим представлением о том, что считать ломающим изменением, и без обязанности с вами советоваться. Основная часть работы уходит в половину, которую вы контролируете; основная часть поломок приходит из той, которую нет.
Речь не о смене одного поставщика модели на другого — у той задачи есть известный ответ: спрятать поставщика за одной дверью. Речь об обычных системах, к которым подключается продукт: CRM, служба поддержки, биллинг. Там абстрагироваться от зависимости нельзя, потому что весь смысл — именно в этой конкретной системе.
Читайте терпимо, пишите строго
Чаще всего интеграция ломается потому, что на той стороне что-то добавили. Парсер, настроенный отвергать незнакомые поля, превращает любое обычное добавление наверху в аварию у вас, притом что поставщик не сделал ничего плохого. Читайте поля, которые используете, остальное игнорируйте и считайте перечислимые значения открытыми: код, который ветвится по статусу и падает на всём незнакомом, сломается в первый же день, когда появится новый статус. Нераспознанную запись откладывайте на просмотр человеком, а не сопоставляйте молча со значением по умолчанию: неверное умолчание хуже падения, потому что о нём вам никто не сообщит.
У терпимости есть цена, которую стоит назвать. Читатель, пропускающий всё незнакомое, пропустит и то изменение, о котором вам нужно было узнать, — поэтому записывайте неизвестные поля и нераспознанные значения в собственные логи. Именно из этой строки лога команды чаще всего и узнают, что поставщик что-то выкатил. Запись — противоположная дисциплина: отправляйте только те поля, которые собираетесь задать, потому что вернуть объект целиком значит записать поверх того, чего вы никогда не понимали; и снабжайте каждую запись ключом идемпотентности, чтобы повтор не превратился во вторую запись.
Фиксируйте что можно и версионируйте собственный коннектор
Если поставщик даёт явные версии API, выберите одну и указывайте её в каждом вызове, а не позволяйте запросам дрейфовать на «текущую». Дрейф удобен ровно до того утра, когда перестаёт им быть. Если фиксировать нечего, заменой служит правило держать все обращения к этому поставщику за одним модулем в своём коде: одно место для правки, когда форма сдвинется, и одно место, чтобы прочитать, от чего вы вообще зависите.
Дайте этому модулю собственную версию и записывайте, какая версия обработала каждую запись. Через три недели вопрос всегда один: каким кодом это сделано, — и интеграция, не умеющая ответить, превращает мелкую правку в раскопки. Та же запись позволяет выкатываться поэтапно — один клиент, одна очередь, процент трафика — пока это ещё не проблема всех.
Считайте, что уведомление об устаревании до вас не дойдёт
Поставщики действительно объявляют об изменениях: в списке изменений, на который никто не подписан, письмом тому, кто заводил аккаунт четыре года назад, и плашкой в панели, которую ваша команда перестала открывать. Подпишитесь на всё, что предлагают, и стройте так, будто не придёт ничего.
Конкретно это означает маленькую скучную канарейку: запланированный вызов каждой нужной вам точки с известным входом и проверкой формы ответа, поднимающий тревогу, когда ответ меняется. Час работы — и это разница между «узнали во вторник утром» и «узнали от клиента». Следите и за самими ответами: многие поставщики предупреждают заголовком задолго до отключения. А срок уведомления считайте самым ненадёжным числом во всей договорённости: он отсчитывается от их публикации, а не от вашего прочтения.
Их авария — ваша, пока вы не решите иначе
Страница статуса — это собственный рассказ поставщика о собственной доступности, публикуемый ответственной за неё командой, и он запаздывает. Пользуйтесь ею, чтобы подтвердить уже возникшее подозрение, но не как источником новости; настоящий сигнал — ваша собственная доля ошибок к этому поставщику.
Что делает ваш продукт, пока вторая сторона недоступна, следует решить, а не обнаружить. Чтение обычно можно отдать устаревшим с честной пометкой об этом. Запись — опасная половина: повторяйте с ключом идемпотентности, ставьте в очередь то, что сейчас не уходит, и ограничьте очередь, чтобы долгая авария не обернулась давкой в момент восстановления. Отказ, который стоит исключить конструкцией, — недописанная запись: у них создано, вам вернулась ошибка, и ничто не сводит одно с другим.
Доступы истекают по чужому расписанию
Доступ к сторонней системе обычно принадлежит клиенту, а не вам, и может быть отозван без всякого предупреждения: отозванный токен, снятое администратором право, удалённый аккаунт, под которым делали подключение. Права ещё и сужаются, ни разу не выдав ошибки: то, что подключение реально может делать, — это пересечение запрошенного вашим приложением, одобренного клиентом и разрешённого его собственной ролью, а последние два меняются без всякой оглядки на вас.
Выжить помогают две привычки. Различайте в своём коде пустой результат и отказ: ошибка прав, обработанная как «записей не найдено», рисует экран, на котором всё в порядке, пока интеграция молча ничего не делает. И сообщайте нужному человеку: пользователь, смотрящий на пустой экран, не может починить отозванный доступ, а администратор, который может, об этом не знает. Интеграция, вежливо сообщающая о поломке не той аудитории, сломана навсегда.
Имейте план на день, когда это выключат
Точки выводят из эксплуатации, бесплатные тарифы закрывают, продукты покупают и складывают внутрь чего-то другого, а условия меняют так, что ваш сценарий оказывается за скобками. На горизонте нескольких лет для хотя бы одной зависимости это почти неизбежность.
Подготовиться не значит построить абстракцию под замену, которую вы не можете назвать. Это значит знать, какие ваши функции перестанут работать, держать собственную копию данных, без которых вы не сможете продолжать обслуживание, и быть честными насчёт недокументированных точек: вызов, найденный подглядыванием за собственным браузером, работает ровно до момента, когда перестаёт, и не несёт никакого срока уведомления. Выпишите по каждому поставщику, что именно сломается и кому об этом сообщать, — это работа на полдня и единственная её часть, которую до объявления сделать проще, чем после.