HTTP-сервис в 1С 8.3: создание, публикация и обработка запросов

· 9 мин

Содержание

HTTP-сервис в 1С создаётся в конфигураторе: ветка дерева конфигурации Общие → HTTP-сервисы, затем шаблоны URL с обработчиками на нужные методы (GET, POST и другие), и в конце — публикация базы на веб-сервере через меню Администрирование → Публикация на веб-сервере. После публикации сервис отвечает по адресу вида http://сервер/база/hs/корневой-url/....

Ниже — весь путь от пустого объекта до рабочего сервиса, который принимает запросы, отдаёт JSON и пускает только авторизованных клиентов. HTTP-сервисы доступны начиная с платформы версии не ниже 8.3.5, так что на актуальной 1С:Предприятие 8.3 всё описанное работает.

Что нужно до начала: веб-сервер и публикация базы

HTTP-сервис сам по себе не отвечает на запросы из сети — его публикует веб-сервер. Поддерживаются два варианта:

  • 🪟 IIS — штатный веб-сервер Windows, ставится через «Программы и компоненты → Включение компонентов Windows».
  • 🐧 Apache — подходит и для Windows, и для Linux-серверов 1С.

При установке платформы отметьте компонент «Модули расширения веб-сервера» — без него публикация не заработает. Если платформа уже стоит, запустите установщик повторно в режиме изменения и добавьте этот компонент.

Сама публикация делается из конфигуратора:

  1. Откройте базу в конфигураторе под пользователем с правами администратора.
  2. Меню Администрирование → Публикация на веб-сервере.
  3. Укажите имя публикации (оно станет частью URL), каталог на диске и выбранный веб-сервер.
  4. Убедитесь, что установлен флажок «Публиковать HTTP-сервисы по умолчанию» либо отметьте конкретные сервисы в списке на соответствующей вкладке.
  5. Нажмите «Опубликовать» и согласитесь на перезапуск веб-сервера.

Платформа создаёт в каталоге публикации файл default.vrd — это описание публикации в формате XML. Все дальнейшие настройки (какие сервисы видны, параметры авторизации) хранятся именно там.

Корневой URL сервиса и имя публикации — разные вещи. Имя публикации задаёте вы при публикации, корневой URL — свойство объекта HTTP-сервис. Итоговый адрес собирается так: /<имя публикации>/hs/<корневой URL>/<шаблон>.

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

Создаём объект HTTP-сервис и шаблоны URL

Теперь — сам объект. В дереве конфигурации найдите ветку Общие → HTTP-сервисы, правый клик → «Добавить».

У нового сервиса заполните два свойства:

  • Имя — внутреннее имя для кода (латиницей, например ObmenDannymi).
  • Корневой URL — то, что попадёт в адрес после /hs/. Короткое слово латиницей, например exchange.

Внутри сервиса создаются шаблоны URL — это маски путей, по которым различаются запросы. Добавьте шаблон и задайте ему свойство «Шаблон». Примеры:

ШаблонЧто ловит
/ordersзапрос к списку заказов
/orders/{id}запрос к одному заказу по номеру
/goods/{code}/stockостаток конкретного товара

Фигурные скобки — это параметры URL. Их значения потом доступны в коде через Запрос.ПараметрыURL["id"].

У каждого шаблона создаются методы — вот здесь и указывается HTTP-метод (GET, POST, PUT, DELETE) и имя процедуры-обработчика. Один шаблон /orders может иметь метод GET (получить список) и метод POST (создать заказ ) — это будут два разных обработчика.

Имя HTTP-метода в свойстве метода пишется заглавными: GET, POST. Если клиент шлёт POST, а у шаблона описан только GET, платформа вернёт код 404, хотя путь совпадает.

Пишем обработчики: разбор запроса и формирование ответа

Обработчик — это экспортная функция в модуле HTTP-сервиса. Она принимает один параметр (входящий запрос) и обязана вернуть объект ответа.

Простейший обработчик GET:

Функция ЗаказыGET(Запрос)
    Ответ = Новый HTTPСервисОтвет(200);
    Ответ.Заголовки["Content-Type"] = "application/json; charset=utf-8";
    Ответ.УстановитьТелоИзСтроки("{""status"": ""ok""}");
    Возврат Ответ;
КонецФункции

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

  • 🔗 Запрос.ПараметрыURL["id"] — значения из фигурных скобок шаблона.
  • ❓ Запрос.ПараметрыЗапроса["page"] — параметры строки запроса после ? (например ?page=2).
  • 📥 Запрос.ПолучитьТелоКакСтроку() — тело запроса (обычно для POST/PUT).
  • 🏷 Запрос.Заголовки["Authorization"] — заголовки запроса.

Код ответа задаётся в конструкторе Новый HTTPСервисОтвет(200). Запомните базовые:

КодКогда возвращать
200успех, данные в теле
201объект создан (ответ на POST)
400клиент прислал некорректные данные
401не авторизован
404объект по такому пути не найден
500ошибка на стороне сервиса

Тело ответа устанавливают либо строкой — УстановитьТелоИзСтроки(...), либо двоичными данными — УстановитьТелоИзДвоичныхДанных(...) (для файлов, картинок, выгрузок).

Методы GET и POST на практике

GET и POST закрывают почти все задачи обмена, поэтому разберём их отдельно.

GET — читаем данные. У такого запроса обычно нет тела, всё приходит в URL. Типовой обработчик: взять параметры, сделать запрос к базе, вернуть результат в теле.

Функция ОстатокGET(Запрос)
    Код = Запрос.ПараметрыURL["code"];
    // ... запрос к регистру остатков по Код ...
    Ответ = Новый HTTPСервисОтвет(200);
    Ответ.Заголовки["Content-Type"] = "application/json; charset=utf-8";
    Ответ.УстановитьТелоИзСтроки(ТелоОтвета);
    Возврат Ответ;
КонецФункции

POST — принимаем данные. Полезная нагрузка приходит в теле запроса. Его надо прочитать и разобрать:

Функция ЗаказPOST(Запрос)
    ТекстЗапроса = Запрос.ПолучитьТелоКакСтроку();
    // ... разбор JSON, запись документа ...
    Ответ = Новый HTTPСервисОтвет(201);
    Возврат Ответ;
КонецФункции

Разница по сути такая:

  • 🟢 GET — безопасен и идемпотентен: сколько раз ни повтори, данные в базе не меняются. Параметры видны в адресе, поэтому не передавайте через него пароли.
  • 🔵 POST — изменяет данные (создаёт документ, записывает справочник). Тело не ограничено длиной URL, подходит для больших пакетов.

Методы PUT (обновить) и DELETE (удалить) описываются так же — меняется только имя HTTP-метода у шаблона и логика внутри.

При записи документов из обработчика оборачивайте действия в транзакцию и обрабатывайте ошибки через Попытка … Исключение. Если запись упала — верните код 500 с понятным текстом в теле, а не «молчаливый» 200.

Работа с JSON: чтение тела и формирование ответа

JSON — основной формат обмена для HTTP-сервисов. В платформе для него есть отдельные объекты.

Разбор входящего JSON (то, что прислал клиент в POST):

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

Функция ПрочитатьJSON возвращает соответствие или массив — с ними дальше работаете как с обычными коллекциями: Данные["Номенклатура"], Данные["Количество"].

Формирование исходящего JSON (то, что сервис отдаёт в теле):

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

Два момента, из-за которых чаще всего ломается кодировка и разбор на стороне клиента:

  1. Всегда ставьте заголовок Content-Type со значением application/json; charset=utf-8. Без явного charset=utf-8 русские буквы на стороне клиента могут прийти «кракозябрами».
  2. Даты. JSON не знает типа «дата», поэтому при записи указывайте формат сериализации дат (например, ISO) через параметры ЗаписатьJSON, иначе принимающая сторона не разберёт значение.

Для выгрузки целых объектов (справочников, документов) удобнее сериализатор XDTO: он сам превращает объект 1С в структуру, а её уже пишете в JSON. Это избавляет от ручного перечисления всех реквизитов.

Авторизация и защита сервиса

HTTP-сервис по умолчанию требует аутентификации пользователя информационной базы — через заголовок Authorization по схеме Basic (логин и пароль). Это задаётся в настройках публикации (файл default.vrd).

Варианты, как пускать клиентов:

  • 🔐 Стандартная аутентификация 1С — клиент передаёт логин/пароль пользователя ИБ. Сеанс создаётся от имени этого пользователя, работают его права. Самый простой и безопасный путь.
  • 🎫 Собственная проверка в коде — отключаете стандартную аутентификацию и внутри обработчика сами проверяете токен из заголовка. Так делают, когда клиент не должен знать пароли пользователей ИБ.
  • 👤 Отдельный технический пользователь — заводите служебного пользователя с минимальными правами только под обмен, остальным доступ к сервису закрываете ролями.

Что критично для безопасности:

Basic-аутентификация передаёт логин и пароль в заголовке почти в открытом виде. Публикуйте сервис только по HTTPS — иначе учётные данные можно перехватить. Сертификат ставится на веб-сервере (IIS/Apache), не в 1С.

  • Не отдавайте через сервис больше данных, чем нужно клиенту: ограничьте роль техпользователя чтением конкретных справочников и регистров.
  • Проверяйте входные данные перед записью: номенклатуру ищите по коду, а не создавайте «на лету» всё, что прислали.
  • Логируйте попытки обращения — это пригодится при разборе инцидентов (см. следующий раздел).
Проверка перед выкладкой сервиса в прод
Выполнено: 0 / 6

Отладка и журналирование работы сервиса

Пока сервис маленький, его удобно отлаживать прямо в конфигураторе. Для этого в параметрах базы включается отладка по протоколу HTTP, а веб-сервер запускается в режиме, разрешающем подключение отладчика. После этого ставите точку останова в обработчике и шлёте запрос из клиента — конфигуратор останавливается на вашей строке.

Если отладчик подключить нельзя (например, прод-сервер), работает старый надёжный способ — журнал регистрации. Внутри обработчика пишите ключевые события:

ЗаписьЖурналаРегистрации("HTTPСервис.Обмен",
    УровеньЖурналаРегистрации.Информация,
    , , "Принят запрос: " + Запрос.ПолучитьТелоКакСтроку());

Для диагностики со стороны клиента удобна утилита типа curl или Postman — они показывают и код ответа, и заголовки, и тело. Минимальная проверка из командной строки:

curl -u Пользователь:Пароль https://сервер/база/hs/exchange/orders

Если в ответ прилетает HTML-страница с ошибкой вместо вашего JSON — запрос до обработчика не дошёл: смотрите на веб-сервер и публикацию. Если приходит ваш JSON, но с ошибкой 500 — проблема уже в коде обработчика, ищите в журнале регистрации.

Частые ошибки и как ускорить сервис

Разберём то, что реально ломает работу, и чего нет в типовых инструкциях.

Ошибка 404 при верном пути. Самая частая причина — метод шаблона описан не на тот HTTP-метод (клиент шлёт POST, в шаблоне только GET) или сервис не отмечен в публикации. Переопубликуйте базу, проверив флажок публикации HTTP-сервисов.

Ответ приходит в неверной кодировке. Нет заголовка Content-Type с charset=utf-8. Проставьте его в каждом ответе.

Сервис «висит» под нагрузкой. Тяжёлый запрос к базе внутри обработчика блокирует сеанс. Что помогает:

  • вынести выборку в запрос с отбором по индексированным полям, а не читать всё и фильтровать в коде;
  • отдавать данные страницами (параметр ?page= и ограничение в запросе), а не весь справочник целиком;
  • не создавать объекты «на каждый вызов» там, где можно переиспользовать;
  • для массовых обменов группировать записи в пакет и обрабатывать одним POST, а не сотней мелких.

Нет обработки исключений. Если обработчик падает без Попытка … Исключение, клиент получает невнятную ошибку веб-сервера. Всегда оборачивайте логику и возвращайте осмысленный код.

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

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

Чем HTTP-сервис отличается от Web-сервиса (SOAP)?
HTTP-сервис работает по REST-подходу: произвольные пути, методы GET/POST, обычно JSON. Публикуется по адресу /hs/. SOAP-сервис строго типизирован через WSDL, обменивается XML-конвертами и публикуется по /ws/. Для обмена с сайтами и мобильными приложениями удобнее HTTP-сервис.
Можно ли вызвать внешний HTTP-сервис из 1С, а не только отдавать свой?
Да, но это другая задача и другие объекты: исходящие запросы делаются через HTTPСоединение и HTTPЗапрос. HTTP-сервис в конфигурации нужен, когда 1С выступает сервером и отвечает на входящие запросы.
Нужна ли отдельная лицензия на HTTP-сервисы?
Отдельной лицензии именно на HTTP-сервисы нет. Но каждый обрабатываемый запрос создаёт сеанс, который занимает клиентскую лицензию на время обработки. При интенсивном обмене закладывайте запас лицензий или используйте сервер 1С с нужным их числом.
Как передать параметр в GET-запрос?
Двумя способами. Через путь — если параметр заложен в шаблон в фигурных скобках (/orders/{id}), берёте его из Запрос.ПараметрыURL. Через строку запроса после ? (/orders?page=2) — берёте из Запрос.ПараметрыЗапроса.
Почему обработчик не видит тело POST-запроса?
Проверьте, что читаете его правильным методом — ПолучитьТелоКакСтроку() для текста/JSON. Если клиент шлёт тело, но указывает метод GET, часть серверов его отбрасывает: для передачи данных используйте POST или PUT.