וואלהבכירים במפלגתו של קנצלר גרמניה הביעו בו תמיכה על רקע הלחץ להתפטרESPNTransfer rumors, news: Barça, Madrid believe Haaland could leave Man City next summerThe Jerusalem PostIDF arrests Iran's Press TV journalist in West Bank, hands her to police, source confirms to 'Post'UN NewsThe world comes to New York: What’s at stake at UN General Assembly high-level weekRTP DesportoOpen de Portugal promovido à primeira divisão do golfe europeuBollywood HungamaAmit Sadh’s Pratap to release in theatres on November 20, 2026; FIRST look unveiledPunchPublic appointments should be based on competence – PRP chieftainInquirerEjercito vows to ensure funding for major railway projectsDigital SpyEmmerdale's Joe Tate to face new revenge plan after Ruby burialVilaWebEl Partit Demòcrata Europeu recorda a Llarena que ha d’aplicar la llei europea i amnistiar PuigdemontBBC NewsCarney's new love-in with EU has everything to do with TrumpGolem.deElon Musk fordert: Unternehmen sollen ihre KI-Systeme gegenseitig prüfen
The Daily Newsstand · Free, Always
Wednesday, September 16, 2026

Как найти причину сбоев внешнего API и исправить её до того, как интеграция попадет в прод

Translate

Меня зовут Андрей Бирюков. Я — независимый эксперт в области ИТ и ИБ, преподаю в учебных центрах и пишу статьи и книги.

В теории все любят красивые диаграммы последовательности, в которых стрелочки летят от сервиса А к сервису Б и обратно. И кажется, что взаимодействие между сервисами осуществляется достаточно просто.

Но в реальности внешний API оказывается черным ящиком, который живет своей жизнью, падает в пятницу вечером и возвращает 404 вместо 200, хотя в документации написано обратное.

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

Как перестать верить документации

Всем известны шутки про инженеров и других мастеров, которые сначала начинают что‑то собирать или настраивать, а только потом читают документацию.

Однако в нашем случае документации действительно лучше не доверять.

Основная ошибка, которую часто допускают разработчики, — написание кода интеграции на основе OpenAPI‑файла, который вам скинули.

Да, Swagger часто генерируется из кода, но, как правило, этот код берется с тестового стенда, а прод, как известно, живет по своим законам.

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

Далее вы просто дернете нужные методы через Postman, а коллеги на той стороне посмотрят, что упадет.

Это займет меньше времени, чем ваше ковыряние в документации.

При выполнении запросов первым делом проведите тест на пустоту, то есть отправьте запрос с минимальными данными.

Например:

  • пустой JSON;

  • массив;

  • отсутствующее обязательное поле.

И вы смотрите не на 200 OK, которые система может не всегда выдавать по делу, а на то, как система сообщает об ошибке.

Аналогичным образом проведите тест на мусор:

  • отправьте в поле phone строку «Дважды два»;

  • в поле date — значение «2026-13-40»;

  • посмотрите код ответа.

Так, при интеграции с банковским сервисом проверки контрагентов в документации было написано:

«Поле INN — 10 или 12 цифр, обязательное. Ошибка 400 — Bad Request».

При проверке на пустоту мы отправляем ИНН длиной 14 символов и в ответ получаем JSON с полем:

"errorCode": "SYS-500"

и текстом:

«Internal Server Error. Обратитесь к администратору».

То есть, если бы мы зашили обработку только на 400, наш API лег бы полностью, потому что внешний сервис валился в 500.

Мы сразу переделали логику:

«Любой код ответа, кроме 200, считаем временной недоступностью и ставим задачу в очередь на повтор через 5 минут».

Но в документации про это не было ни слова.

Итак, мы отучились верить документации и дальше нам надо отвыкнуть бездумно принимать все то, что нам отдает смежная система.

Про толстый слой грязи

Безопасники любят говорить, что нельзя доверять тем данным, которые могут прийти от пользователя.

Здесь то же самое: никогда не отдавайте сырые объекты внешнего API внутрь своей бизнес‑логики.

Внешняя система может сегодня вернуть:

{
  "name": "Иван"
}

а завтра решит переименовать поле:

{
  "clientName": "Иван"
}

И в итоге ваша система упадет, даже не начав работать.

Для того чтобы решить эту проблему, нам необходимо построить «Толстый Адаптер».

Это должна быть не просто прослойка, это бункер, который принимает на себя весь удар хаоса.

Давайте рассмотрим основные принципы проектирования адаптера.

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

Соответственно, нужно быть готовым к тому, что какие‑то поля будут иметь не тот тип или вообще отсутствовать.

А дальше строим так называемую схему с приоритетами.

Например:

  • Если поле id не пришло — мы не можем работать, выбрасываем ошибку (это критично).

  • Если поле description не пришло — подставляем значение по умолчанию «Описание временно недоступно» и логируем факт отсутствия.

  • Если поле price пришло в виде строки «1 200,50 ₽» — ваш адаптер парсит это в число, отрезая лишнее.

В итоге в случае критичных изменений в полученных данных мы просто завершим работу с внятной ошибкой.

А если изменение формата не критично — мы распарсим его.

Еще одна схема обработки ошибок — так называемый «Сломанный телефон».

Здесь вы пишете метод:

fetchData()

без параметров.

Внутри этого метода мы будем ловить абсолютно все исключения:

  • таймауты;

  • SSL‑ошибки;

  • NullPointer;

  • невалидный JSON;

  • прочие неприятности.

Если поймали — мы не будем кидать эту ошибку дальше в бизнес‑логику, а вместо этого просто вернем специальный внутренний объект:

Result<T>

Например, если мы интегрируемся с сервисом доставки, то нам важно получать статус заказа. При этом, поле status может быть: "1", "2", "delivered", "IN_PROGRESS", а иногда вообще null.

Вместо того чтобы править всю логику расчета сроков доставки, наш адаптер внутри делает так:

  • если status == null или status == "1" → возвращаем наш внутренний ORDER_STATUS.PENDING;

  • если status == "delivered"ORDER_STATUS.DONE.

В результате разработчики фронтенда вообще не знали, что там за зоопарк творится.

Они работали с чистыми тремя состояниями:

  • PROGRESS;

  • PENDING;

  • DONE.

И всех это устраивало.

Техника двух спецкейсов

Когда документация врет, самым важным артефактом для аналитика становится даже не схема данных, а так называемый список пограничных негативных тестов.

Вы должны составить его до того, как разработчик начнет писать метод.

Есть два магических сценария, которые спасают 90% интеграций.

Сценарий № 1. «Долгая пауза»

Здесь нам надо разобраться с таймаутами.

А именно, спросите внешнюю команду:

«Если ваш сервис думает 30 секунд, а потом отвечает „ОК“, мы должны ждать?»

Скорее всего они скажут:

«Нет, мы обычно отвечаем за 500 мс».

Но все та же документация этого никак не гарантирует.

В результате вы пишете в своем ТЗ:

«Если внешний сервис не ответил за 5 секунд — мы считаем это ошибкой и не ждем. Ставим задачу в очередь Retry с экспоненциальной задержкой (1 мин, 5 мин, 15 мин)».

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

Сценарий № 2. «Частичный успех»

Представим ситуацию, когда внешний API принимает массив из 100 заказов.

В документации написано:

«Вернет массив результатов».

А по факту, если в пачке один заказ сломан (невалидный номер), внешний сервис часто возвращает ошибку 500 на все заказы и не обрабатывает остальные 99.

Здесь вам не нужно сразу отправлять пачку заказов.

Вместо этого вы говорите:

«Отправляем по одной сущности, несмотря на то, что это займет больше времени. Но тогда мы точно будем знать, какой заказ упал, и сможем переотправить только его, а не весь список».

Если же архитектура жестко требует пачки, вы проектируете на своей стороне «Детектор битых сущностей».

Суть его заключается в отправке всех ста заказов.

Однако в случае ошибки:

  1. анализируем ответ;

  2. если там есть хотя бы намек на ID сбойной записи;

  3. повторяем запрос уже без этой записи.

Например, мы обмениваемся данными с государственной системой ЕГАИС, отправляя акты из 50 позиций.

В документации было указано:

«При успехе вернет 200».

На проде мы получили ответ с кодом 200, но внутри JSON было поле:

"warnings"

с текстом:

«Позиция № 4 не найдена в справочнике, акт зарегистрирован без нее».

То есть, вроде работает, но не совсем.

Если бы мы обрабатывали только код 200, мы бы не увидели, что потеряли позицию.

Поэтому в адаптере мы сделали правило:

«Если в ответе есть warnings или errors — считать транзакцию неуспешной и бить тревогу, даже если код 200».

Подведем итог

Ваша задача как аналитика — не нарисовать красивые стрелочки, а ответить на вопросы о рисках интеграции.

Например:

Что делать, если пришел не JSON, а HTML с ошибкой 502?

В таком случае наш адаптер парсит ошибку и возвращает статус:

UNAVAILABLE

Или:

Что делать, если пришел ответ, но в нем не хватает трех обязательных полей?

Здесь приложение ни в коем случае не должно падать.

Оно должно:

  • логировать это событие как «Сервис прислал битые данные»;

  • либо подставлять заглушки;

  • либо сохранять то, что есть, с пометкой:

NEED_MANUAL_CHECK

И не забываем про идемпотентность.

То есть можем ли мы повторить запрос без последствий?

Если нет — мы не используем автоматический ретрай, а только выдаем уведомление оператору.

В заключение запомните простое правило:

Надежная интеграция начинается не с вопроса «Как это работает по документации?», а с вопроса «Как это сломается в 3 часа ночи, и чтобы мы не проснулись?».

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

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

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

  • 23 сентября в 20:00. «Как системному аналитику проводить архитектурное ревью и находить риски до начала разработки». Записаться

  • 6 октября в 20:00. «Практические подходы к переходу от монолита на микросервисы». Записаться

  • 22 октября в 19:00. «Основы проектирования бизнес‑логики в микросервисной архитектуре». Записаться

А все бесплатные уроки сентября можно посмотреть в дайджесте.

View the original on Хабр

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.