Практика осознанного программирования на примере разработки библиотеки 1С Ozon
Библиотека интеграции с Ozon — не просто очередной модуль для обмена данными. Она стала полигоном для отработки принципов осознанного программирования: от управления HTTP-соединениями до обработки асинхронных колбэков. Разбор реальной архитектуры библиотеки выявил ловушки, которые обходятся в часы отладки, если мысль разработчика движется по инерции «лишь бы работало». Ниже — нетривиальный опыт, а не пересказ общих принципов.
Почему осознанность в HTTP-интеграциях — не роскошь, а необходимость
Стандартный подход к написанию кода интеграции выглядит так: создали HTTP-соединение, отправили запрос, получили ответ, обработали. Всё. Однако на примере библиотеки Ozon (открытый модуль на Infostart) видно, как троекратно возрастает сложность, если не закладывать механизмы повторных попыток, управления квотой запросов и корректного завершения сессии.
Рядовой специалист часто пишет:
Соединение = Новый HTTPСоединение("api.ozon.ru", 443,,, Новый ЗащищенноеСоединениеOpenSSL());
Запрос = Новый HTTPЗапрос();
Запрос.Заголовки.Вставить("Content-Type", "application/json");
// ... заполнение тела
Ответ = Соединение.ВызватьHTTPМетод("POST", "/v3/product/info", Запрос);
Если Ответ.КодСостояния = 200 Тогда
// разбор
Иначе
Сообщить("Ошибка");
КонецЕсли;
Проблема в том, что в экосистеме Ozon код состояния 200 не гарантирует успеха — API может вернуть
application/jsonс"status": false. Кроме того, при превышении rate‑limit (429) соединение не должно переиспользоваться без задержки. Отсутствие обработки таймаутов приводит к «зависаниям» фоновых заданий.
Ловушка «одноразового соединения»
В документации 1С сказано, что HTTPСоединение не предназначено для хранения в глобальном контексте и автоматически пересоздаёт канал при каждом вызове ВызватьHTTPМетод, если объект был разрушен. Но многие разработчики ошибочно полагают, что повторное использование одного экземпляра ускоряет работу. На самом деле библиотека Ozon использует пул с дефолтным Keep-Alive, и если не закрыть соединение явно, может возникнуть утечка дескрипторов под нагрузкой.
Осознанное решение — не кэшировать HTTPСоединение в переменных модуля менеджера, а создавать его по мере необходимости и после выполнения запроса обнулять ссылку (что триггерит финализацию).
Управление состоянием: когда ошибка — не ошибка
Асинхронные колбэки Ozon: как не потерять данные
Ozon для длительных операций (например, генерация отчётов) использует асинхронный паттерн: первый запрос возвращает task_id, а статус нужно опрашивать через /v1/task/get. Разработчики часто пишут цикл ожидания с Задержка() внутри HTTP-вызова, что блокирует поток. Правильная реализация — вынести опрос в отдельное фоновое задание с контролем количества попыток.
В библиотеке применяется приём: если сервер возвращает 202 Accepted, то задача создаётся, а последующая обработка вынесена в процедуру ДождатьсяВыполненияЗадачи():
Функция ДождатьсяВыполненияЗадачи(Токен, ИДЗадачи, МаксПопыток = 60) Экспорт
Попытка = 0;
Пока Попытка < МаксПопыток Цикл
Ответ = ОтправитьЗапрос("POST", "/v1/task/get", Новый Структура("task_id", ИДЗадачи));
ТелоОтвета = ПрочитатьОтвет(Ответ);
Если ТелоОтвета.Статус = "OK" Тогда
Возврат ТелоОтвета.Результат;
КонецЕсли;
Попытка = Попытка + 1;
Промедление(1000); // 1 секунда
КонецЦикла;
ВызватьИсключение "Превышено время ожидания выполнения задачи Ozon";
КонецФункции
Здесь осознанность в том, что
Промедлениев основном потоке допустимо только при явном контроле максимума попыток и в сценариях, где есть перспектива отмены. В противном случае фоновое задание может зависнуть на часы.
Обработка накладных: почему нельзя хранить только ID
Многие примеры в сети советуют сохранять в 1С лишь внешние идентификаторы заказов. Однако Ozon меняет их при перевыставлении, а в POST‑запросах требуется версия объекта. Осознанный подход — хранить в отдельном регистре не только ID, но и поле Версия, и hash последнего отправленного тела (чтобы избежать дублирования).
Практическое руководство: три шага к осознанной интеграции
Шаг 1. Проектируйте обработку ошибок от «внешних» к «внутренним»
Сначала разберите HTTP-статусы: 400, 401, 403, 404, 422, 429, 500, 502, 503. Для каждого пропишите сценарий. Для 429 — экспоненциальная задержка с записью в журнал. Для 422 — запись ошибки в документ без повтора. Это не инструкция, а правило: не смешивайте логику бизнес-исключений с сетевыми.
Шаг 2. Используйте шаблон «Ретри-сервис»
В библиотеке Ozon можно встретить класс (через реальный API ИТС) РаботаСОшибками, который инкапсулирует count попыток, лимит времени и признак идемпотентности запроса. Если запрос можно повторить без побочных эффектов, ретри выполняется с паузой; если нет — генерируется исключение.
Шаг 3. Управляйте сессией аутентификации
Ozon использует Bearer‑токен с ограниченным сроком. Типичная ошибка — получать токен каждый запрос. Правильный вариант — кэшировать токен в структуре конфигурации (например, регистр сведений) и обновлять только при получении 401. Осознанный подход: проверять подпись отклонённого запроса — если 401, выполнить обновление и повторить исходный запрос.
Типичные ошибки и контрольный список
- Смешение ролевых обработчиков — в одной процедуре выполняется парсинг JSON, проверка бизнес-логики и запись в регистры. Это нарушает принцип единственной ответственности.
- Игнорирование заголовка
Retry-After— многие серверы возвращают время ожидания, но код 1С не использует его, полагаясь на фиксированную задержку. - Отсутствие автоматического отключения при недоступности API — если API недоступно 10 минут, фоновые задания продолжают долбить его, увеличивая нагрузку на 1С.
- Запись лога в базу данных — в реальной эксплуатации лог интеграции лучше вести в текстовый файл с ротацией, а в базу — только критические ошибки.
Что делать прямо сейчас
- Откройте модули обмена с любым внешним сервисом в вашей конфигурации.
- Убедитесь, что
HTTPСоединениесоздаётся локально в каждой функции, а не в переменных модуля. - Проверьте обработку HTTP-статуса 429: есть ли
ПопыткасПромедлениеи проверка заголовкаRetry-After? - Зафиксируйте таймаут соединения (
Таймаутв HTTPСоединение) — не менее 30 секунд для API Ozon. - Реализуйте простой счётчик неудачных запросов за последние 5 минут; при превышении порога прекращайте отправку до административного сброса.
Осознанное программирование в интеграциях не требует сверхсложных паттернов, но дисциплины «почему это сделано так». Библиотека Ozon — отличный пример, где за кажущейся простотой скрываются десятилетия практических ошибок.
Попробовать НОПик →