Входящий HTTP-запрос в 1С 8.3: от шаблона URL до ответа JSON

· 9 мин

Содержание

Чтобы обработать запрос в 1С, создайте HTTP-сервис в ветке Общие → HTTP-сервисы, задайте шаблон URL и метод, а в процедуре-обработчике прочитайте объект HTTPСервисЗапрос и верните HTTPСервисОтвет с кодом состояния. Всё, что не вернуло ответ или упало исключением, клиент увидит как код 500.

Частое заблуждение — считать, что 1С «сама» разберёт JSON и проверит данные. Нет: платформа только сопоставит адрес с шаблоном и проверит пользователя. Разбор тела, проверки, коды ошибок и журнал — работа разработчика. Ниже по шагам, с кодом, который можно взять за основу.

Как устроен HTTP-сервис в 1С и куда приходит запрос

HTTP-сервис — объект метаданных конфигурации. У него три уровня:

  • 🌐 Корневой URL — свойство сервиса, например api. Это первая часть адреса.
  • 🧩 Шаблоны URL — пути внутри сервиса: /orders, /orders/{id}. В фигурных скобках — параметры.
  • ⚙️ Методы — у каждого шаблона свой набор: GET, POST, PUT, DELETE и другие. Каждому методу назначается функция-обработчик в модуле сервиса.

Полный адрес после публикации выглядит так:

http://сервер/ИмяПубликации/hs/КорневойURL/шаблон
http://srv01/trade/hs/api/orders/000123

Сегмент hs добавляет платформа — он отличает HTTP-сервисы от веб-сервисов (ws) и OData.

Создание сервиса в конфигураторе

  1. В дереве конфигурации откройте Общие → HTTP-сервисы и добавьте новый объект.
  2. Заполните Корневой URL, например api.
  3. На вкладке шаблонов добавьте шаблон /orders/{id}.
  4. Внутри шаблона добавьте метод GET.
  5. В свойствах метода нажмите кнопку открытия у поля Обработчик — конфигуратор создаст в модуле функцию с параметром Запрос.

Публикация на веб-сервере

Сервис работает только через веб-сервер (Apache или IIS) с модулем расширения 1С. Публикуют его из конфигуратора: Администрирование → Публикация на веб-сервере. На вкладке HTTP-сервисов должен стоять флажок публикации, а нужный сервис — отмечен.

Публиковать можно и файловую базу. Для отладки этого достаточно: локальный Apache и файловая копия рабочей базы.

Алгоритм обработки входящего запроса в 1С

Хороший обработчик всегда идёт по одному порядку. Отступление от него — главный источник «плавающих» ошибок.

  1. Проверить метод и параметры адреса.
  2. Прочитать тело и разобрать формат.
  3. Проверить данные: обязательные поля, типы, существование объектов.
  4. Выполнить действие: найти, создать, изменить.
  5. Сформировать ответ с кодом и телом.

Всё, кроме пятого шага, оборачивается в Попытка … Исключение.

Что лежит в объекте HTTPСервисЗапрос

Свойство или методЧто содержит
HTTPМетодСтрока: GET, POST и т. д.
ПараметрыURLЗначения из фигурных скобок шаблона (id)
ПараметрыЗапросаПараметры после ?: ?limit=50&page=2
ЗаголовкиЗаголовки запроса, например Content-Type
ОтносительныйURLПуть после корневого URL
ПолучитьТелоКакСтроку()Тело текстом
ПолучитьТелоКакДвоичныеДанные()Тело для файлов и картинок

Чтение параметров и тела

Параметры адреса и строки запроса читайте через Получить(): если ключа нет, вернётся Неопределено, а не исключение.

Функция ЗаказGET(Запрос)

    Номер = Запрос.ПараметрыURL.Получить("id");
    Лимит = Запрос.ПараметрыЗапроса.Получить("limit");

    Если Не ЗначениеЗаполнено(Номер) Тогда
        Возврат ОтветОшибка(400, "Не указан номер заказа");
    КонецЕсли;

    // поиск и формирование ответа
    // ...

КонецФункции

Тело POST-запроса с JSON разбирают так:

Функция ЗаказыPOST(Запрос)

    Тело = Запрос.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
    Если ПустаяСтрока(Тело) Тогда
        Возврат ОтветОшибка(400, "Пустое тело запроса");
    КонецЕсли;

    Попытка
        Чтение = Новый ЧтениеJSON;
        Чтение.УстановитьСтроку(Тело);
        Данные = ПрочитатьJSON(Чтение, Истина);
        Чтение.Закрыть();
    Исключение
        Возврат ОтветОшибка(400, "Некорректный JSON");
    КонецПопытки;

    Если Данные.Получить("customer") = Неопределено Тогда
        Возврат ОтветОшибка(422, "Не заполнено поле customer");
    КонецЕсли;

    // создание документа
    // ...

КонецФункции

Второй параметр ПрочитатьJSON(Чтение, Истина) возвращает Соответствие вместо Структура. Это обязательно для внешних данных: ключ вида order-id или 1c_code в структуру не ляжет, и чтение упадёт.

Как сформировать ответ клиенту

Ответ — объект HTTPСервисОтвет. Первый параметр конструктора — код состояния.

Функция ОтветJSON(КодСостояния, Данные)

    Запись = Новый ЗаписьJSON;
    Запись.УстановитьСтроку();
    ЗаписатьJSON(Запись, Данные);
    Текст = Запись.Закрыть();

    Ответ = Новый HTTPСервисОтвет(КодСостояния);
    Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
    Ответ.УстановитьТелоИзСтроки(Текст, КодировкаТекста.UTF8,
        ИспользованиеByteOrderMark.НеИспользовать);
    Возврат Ответ;

КонецФункции

Функция ОтветОшибка(КодСостояния, Сообщение)

    Данные = Новый Структура("error", Сообщение);
    Возврат ОтветJSON(КодСостояния, Данные);

КонецФункции

Две детали, на которых спотыкаются чаще всего:

  • 🔤 BOM. Без ИспользованиеByteOrderMark.НеИспользовать в начало тела может попасть метка порядка байтов. Часть клиентов на JavaScript и PHP после этого не разбирает JSON.
  • 🔗 Ссылки. ЗаписатьJSON не сериализует ссылки на справочники и документы. Перед записью превращайте их в строку: код, номер или Строка(Ссылка.УникальныйИдентификатор()).

Какие коды состояния возвращать

КодКогдаПример
200Данные найдены и отданыGET заказа
201Объект созданPOST нового заказа
202Принято, обработка позжеЗапуск фонового задания
400Запрос сломанНевалидный JSON, нет параметра
401Не прошла авторизацияНеверный логин (отдаёт сама платформа)
403Нет прав на действиеПользователь без нужной роли
404Объект не найденЗаказ с таким номером отсутствует
409КонфликтДокумент уже проведён или заблокирован
422Данные не прошли проверкуНет обязательного поля
500Ошибка на стороне 1СИсключение при записи

Если путь не совпал ни с одним шаблоном, платформа сама вернёт 404 — ваш код даже не вызовется.

Обработка ошибок и исключений в HTTP-сервисе

Необработанное исключение 1С превращает в ответ 500, а в тело кладёт текст ошибки. Для внешнего клиента это плохо дважды: он не понимает, что делать, и видит внутренние имена объектов.

Правильная схема — перехватить исключение, записать подробности в журнал регистрации, а клиенту вернуть короткое сообщение:

Попытка
    НачатьТранзакцию();
    СоздатьЗаказ(Данные);
    ЗафиксироватьТранзакцию();
Исключение
    ОтменитьТранзакцию();
    Подробно = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
    ЗаписьЖурналаРегистрации("HTTPСервис.Заказы",
        УровеньЖурналаРегистрации.Ошибка, , , Подробно);
    Возврат ОтветОшибка(500, "Не удалось создать заказ. Обратитесь к администратору");
КонецПопытки;

Разделяйте ошибки клиента и свои. Нет поля, неверный формат даты, неизвестный код товара — это 400 или 422 с понятным текстом. Сбой записи, блокировка, нехватка прав у служебного пользователя — 500 или 409.

Не возвращайте 200 с текстом {"error": "..."}. Интегратор будет проверять только код и примет ошибку за успех.

Повторные запросы

Клиенты при таймауте часто повторяют POST. Без защиты в базе появятся два одинаковых заказа. Приём практиков — ключ идемпотентности: клиент передаёт свой номер заявки, а сервис перед созданием ищет документ с таким внешним номером. Нашёл — возвращает 200 с уже созданным объектом, а не создаёт второй.

Авторизация и безопасность запросов к 1С

По умолчанию HTTP-сервис требует Basic-авторизацию пользователем информационной базы. Логин и пароль клиент передаёт в заголовке Authorization, 1С сверяет их со списком пользователей. Не прошла проверка — платформа сама отвечает 401.

Что стоит сделать для рабочей интеграции:

  • 👤 Отдельный пользователь под интеграцию с минимальной ролью. Не используйте учётную запись администратора.
  • 🔤 Латиница в логине. Кириллица в Basic-авторизации ломается на клиентах с другой кодировкой — надёжнее api_trade.
  • 🔒 Только HTTPS. Basic передаёт пароль в обратимом виде. Без TLS его прочитает любой, кто видит трафик.
  • ✅ Проверка прав в коде. Для чувствительных действий проверяйте РольДоступна("ИмяРоли") и возвращайте 403.

Привилегированный режим

Иногда служебному пользователю не хватает прав на чтение регистра, а давать роль целиком не хочется. Тогда в обработчике точечно включают УстановитьПривилегированныйРежим(Истина) на время операции. Включайте его только после проверки входных данных, иначе любой клиент получит полный доступ к тому, что делает метод.

Анонимный доступ

Для приёма вебхуков от сторонних сервисов, которые не умеют Basic, пользователя прописывают в строке подключения публикации (default.vrd). Тогда авторизация 1С не спрашивается вообще. В таком режиме проверяйте секретный токен в заголовке запроса сами и закройте публикацию на веб-сервере по IP-адресам отправителя.

Производительность обработки запросов

Повторное использование сеансов

У HTTP-сервиса есть свойство Повторное использование сеансов. Без него на каждый запрос платформа открывает новый сеанс: авторизация, запуск модулей сеанса, захват лицензии. Это десятки и сотни миллисекунд на пустом месте.

ЗначениеКак работаетКогда брать
Не использоватьНовый сеанс на каждый запросРедкие вызовы, отладка
ИспользоватьКлиент сам держит сеанс через cookieСвой клиент, который умеет хранить cookie
Автоматически использоватьПлатформа держит пул сеансовБольшинство интеграций

Рядом задаётся Время жизни сеанса в секундах — сколько сеанс ждёт следующего запроса.

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

Что ещё ускоряет ответ

  • 📄 Пагинация. Списки отдавайте частями через ?limit=&page=, а не всю таблицу разом. Ставьте верхний предел — например, 500 строк.
  • 🔎 Запрос вместо обращения через точку. Выборка нужных полей одним запросом быстрее, чем Заказ.Контрагент.ИНН в цикле по строкам.
  • ⏳ Долгие операции в фоне. Пересчёт, загрузку тысяч строк, проведение пакета документов запускайте через ФоновыеЗадания.Выполнить() и сразу отвечайте 202 с идентификатором задания. Статус клиент спросит отдельным GET.
  • 🧮 Короткие транзакции. Держите транзакцию только вокруг записи, без HTTP-вызовов наружу и без тяжёлых выборок внутри. Иначе запросы начнут ждать друг друга на блокировках.

Диагностика и логирование HTTP-запросов

Первый инструмент — curl. Он есть в Windows 10 и новее, в Windows Server 2019 и в любом Linux. Так вы отделяете проблемы сервиса от проблем клиента:

curl -i -u api_trade:Пароль ^
  -H "Content-Type: application/json" ^
  -d "{\"customer\":\"7701234567\"}" ^
  http://srv01/trade/hs/api/orders

Ключ -i покажет код и заголовки ответа. В Linux вместо ^ в конце строк ставьте \.

Где искать следы

  • 📒 Журнал регистрации. Сюда пишет ваш ЗаписьЖурналаРегистрации. Отбирайте по имени события, например HTTPСервис.Заказы.
  • 🌐 Лог веб-сервера. Если запрос не дошёл до 1С (404 от Apache, 503), ответ — в access и error логах Apache или IIS.
  • 🛠 Технологический журнал. Настраивается файлом logcfg.xml в каталоге conf платформы. Событие EXCP покажет исключения, которые не попали в ваш журнал.
  • 🐞 Отладка. В конфигураторе подключите отладку HTTP-сервисов: на клиенте и в публикации должна быть включена отладка. Точка останова в обработчике сработает при вызове из curl.

Логируйте и успешные вызовы, но коротко: метод, адрес, код ответа, время. Тело пишите только для ошибок — иначе журнал разрастётся за неделю.

Диагностика: выберите симптом

Ошибки, которые ломают HTTP-сервис в 1С

  • ❌ Изменили шаблон — забыли обновить публикацию. Конфигурация обновлена, а веб-сервер работает со старым составом. Переопубликуйте базу.
  • ❌ Чтение JSON в структуру. Падает на первом ключе с дефисом или цифрой в начале.
  • ❌ Одна функция на все методы без проверки HTTPМетод. Если на шаблон назначен общий метод *, сравнивайте метод сами, иначе DELETE выполнит код POST.
  • ❌ Сравнение строк без учёта регистра. Ключи Соответствие из JSON чувствительны к регистру: Customer и customer — разные ключи. Договоритесь с клиентом о формате и проверяйте ровно его.
  • ❌ Даты без формата. Клиент шлёт 2026-10-07T10:00:00+03:00, а код ждёт ГГГГММДД. Для дат в JSON используйте функцию ПрочитатьДатуJSON с подходящим форматом.
  • ❌ Обращение к клиентским методам. Модуль HTTP-сервиса выполняется на сервере: Сообщить() и диалоги там бесполезны, всё выводится в ответ или журнал.

Частые вопросы

Можно ли получить тело в GET-запросе?
Технически 1С его прочитает, но многие прокси и клиенты тело у GET отбрасывают. Параметры GET передавайте в строке запроса и читайте через ПараметрыЗапроса.
Как вернуть файл, например PDF счёта?
Сформируйте двоичные данные и установите их методом УстановитьТелоИзДвоичныхДанных. Добавьте заголовки Content-Type: application/pdf и Content-Disposition с именем файла.
Почему браузерный JavaScript получает ошибку CORS?
Браузер сначала шлёт запрос OPTIONS. Добавьте на шаблон метод OPTIONS, который отвечает 200 с заголовками Access-Control-Allow-Origin, Access-Control-Allow-Methods и Access-Control-Allow-Headers, и тот же Access-Control-Allow-Origin возвращайте в основных ответах.
Нужна ли отдельная лицензия на вызовы HTTP-сервиса?
Каждый сеанс HTTP-сервиса потребляет клиентскую лицензию так же, как пользователь. Повторное использование сеансов снижает их число при частых вызовах.
Чем HTTP-сервис лучше OData для интеграции?
OData отдаёт объекты базы почти без кода, но наружу видна структура метаданных. HTTP-сервис требует программирования, зато вы сами решаете, какие поля отдать и какие проверки выполнить.