HTTP-сервисы в 1С: от объекта конфигурации до первого ответа

· 10 мин

Содержание

HTTP-сервис в 1С — это объект конфигурации, который принимает запросы по протоколу HTTP и возвращает ответ: строку, JSON, XML или файл. Работает он так: внешняя система (сайт, мобильное приложение, другая учётная программа) обращается к опубликованному адресу вида http://сервер/база/hs/..., платформа подбирает подходящий обработчик и выполняет ваш код на встроенном языке.

Чтобы такой сервис заработал, нужны три вещи: сам объект «HTTP-сервис» в дереве конфигурации, публикация базы на веб-сервере (IIS или Apache) и платформа 1С версии не ниже 8.3.5 — именно в ней появился этот механизм.

Что происходит, когда приходит запрос

Входящий HTTP-запрос сначала попадает не в 1С, а на веб-сервер. IIS или Apache принимает соединение, разбирает адрес и по префиксу /hs/ понимает, что обращение адресовано HTTP-сервису конкретной информационной базы.

Дальше в работу вступает модуль расширения веб-сервера — библиотека, которую ставят при публикации. Она передаёт запрос платформе 1С, та поднимает сеанс (в клиент-серверном варианте — через рабочий процесс кластера) и ищет сервис, у которого корневой URL и шаблон адреса совпадают с пришедшей ссылкой.

Когда совпадение найдено, платформа вызывает функцию-обработчик, привязанную к методу. Внутри обработчика доступны данные базы: справочники, документы, регистры. Результат вы упаковываете в объект ответа, и он тем же путём возвращается клиенту.

Для HTTP-сервисов в адресе используется префикс /hs/. У SOAP-сервисов (web-сервисов) это /ws/, у стандартного интерфейса OData — /odata/. Перепутанный префикс — частая причина ответа 404.

Веб-сервер здесь не просто «труба». Он отвечает за TLS (HTTPS), за базовую аутентификацию по заголовку Authorization, за ограничение размера тела запроса и за балансировку, если публикаций несколько. Поэтому настройка делится на две зоны: что делает 1С и что делает веб-сервер.

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

Объекты конфигурации: сервис, шаблон URL и метод

Механизм строится на трёх уровнях вложенности. Создаются они в конфигураторе, в ветке Общие → HTTP-сервисы.

  1. HTTP-сервис. Верхний объект. Его главное свойство — Корневой URL: короткое имя, которое встанет в адрес после /hs/. Например, корневой URL catalog даёт базовую ссылку .../hs/catalog.
  2. Шаблон URL. Описывает путь внутри сервиса. В шаблоне можно задать переменные части в фигурных скобках: /products/{id}. Значение из адреса потом доступно в коде.
  3. Метод. Привязан к шаблону. У метода есть свойство HTTP-метод (GET, POST, PUT, DELETE и другие) и свойство Имя обработчика — имя функции в модуле сервиса.

Один шаблон обычно держит несколько методов: GET на /products/{id} отдаёт товар, DELETE на том же шаблоне его удаляет. Платформа сама выберет нужный метод по глаголу запроса.

Весь код живёт в модуле HTTP-сервиса. Открывается он так же, как модуль любого объекта, — через контекстное меню в дереве конфигурации.

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

Пока сервис не опубликован, вызвать его нельзя. Публикация выполняется из конфигуратора: Администрирование → Публикация на веб-сервере….

В окне публикации:

  1. Задайте имя — оно станет частью адреса (http://сервер/имя/...) и именем каталога на диске.
  2. Укажите каталог, куда положить файлы публикации, и выберите веб-сервер.
  3. Перейдите на вкладку HTTP-сервисы и отметьте флажками те сервисы, которые нужно опубликовать.
  4. Нажмите Опубликовать.

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

После этого адрес собирается по схеме:

http://<сервер>/<имя публикации>/hs/<корневой URL>/<путь из шаблона>

Для корневого URL catalog и шаблона /products/{id} полный GET-адрес выглядит так:

http://server/base/hs/catalog/products/000000123

Фрагмент 000000123 попадёт в переменную id шаблона.

Модуль расширения веб-сервера должен совпадать по разрядности с веб-сервером (x86/x64) и быть той же версии, что и платформа. Несовпадение даёт ошибку 500 или пустую страницу ещё до того, как выполнится хоть одна строка вашего кода.

Перед публикацией сервиса проверьте
Выполнено: 0 / 6

Код обработчика: разбираем запрос и собираем ответ

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

Из входящего запроса доступны:

  • Запрос.ПараметрыURL — соответствие с переменными шаблона (то, что в фигурных скобках).
  • Запрос.ПараметрыЗапроса — параметры из строки запроса после ? (например, ?limit=50).
  • Запрос.Заголовки — соответствие заголовков.
  • Запрос.Метод — HTTP-метод строкой.
  • Запрос.ПолучитьТелоКакСтроку() — тело запроса текстом.
  • Запрос.ПолучитьТелоКакДвоичныеДанные() — тело в двоичном виде (для файлов).

Ответ создаётся конструктором с кодом состояния, в него кладут заголовки и тело:

Функция ПолучитьТовар(Запрос)

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

    Ссылка = Справочники.Номенклатура.НайтиПоКоду(Код);
    Если Ссылка.Пустая() Тогда
        Возврат Новый HTTPСервисОтвет(404);
    КонецЕсли;

    Данные = Новый Структура;
    Данные.Вставить("код", Ссылка.Код);
    Данные.Вставить("наименование", Ссылка.Наименование);

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

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

    Возврат Ответ;

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

Функция возвращает товар, если он найден, и код 404, если нет. Такой контракт — найден объект или нет — лучше задать сразу, иначе клиент получит пустой успех и не поймёт, что искать было нечего.

Заголовок Content-Type с указанием charset=utf-8 ставьте всегда, когда отдаёте текст или JSON. Без него клиент может принять кириллицу за другую кодировку и показать «кракозябры».

Обмен данными в JSON и XML

JSON — основной формат для HTTP-сервисов. Платформа работает с ним через пару объектов: ЗаписьJSON для сериализации и ЧтениеJSON для разбора.

Чтобы отдать JSON, структуру или соответствие превращают в строку (как в примере выше). Вложенные структуры и массивы сериализуются автоматически — удобно собирать ответ из Массив структур.

Чтобы принять JSON из тела POST-запроса:

ТелоЗапроса = Запрос.ПолучитьТелоКакСтроку();

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

Наименование = Данные.Получить("наименование");

ПрочитатьJSON по умолчанию возвращает соответствие, где ключи — имена свойств JSON. Отдельно стоит продумать даты: в JSON нет типа «дата», поэтому её передают строкой в формате ISO, а при чтении преобразуют вручную или через параметры функции чтения.

XML используют, когда этого требует принимающая сторона — обмен с госсистемами, старые интеграции, SOAP-соседи. Для произвольной структуры подойдут ЧтениеXML/ЗаписьXML, а для объектов 1С — сериализация через фабрику XDTO. XML многословнее JSON и его тело заметно тяжелее, поэтому для новых интеграций обычно выбирают JSON.

Таблица поможет выбрать формат:

КритерийJSONXML
Объём телакомпактнеетяжелее
Поддержка в вебе и мобильныхпо умолчаниюреже
Строгая схема и валидацияслабаясильная (XSD)
Обмен с 1С и госсистемамиограниченночасто требуется

Методы GET, POST, PUT, DELETE: что отдавать и какой код вернуть

HTTP-метод — это не просто пометка, а обещание клиенту о характере операции. Нарушать семантику не стоит: кэши, прокси и фреймворки на стороне клиента рассчитывают на стандартное поведение.

  • 🔎 GET — чтение. Ничего не меняет в базе, безопасен, его можно повторять. Проверить такой метод проще всего — вставить адрес в браузер.
  • ➕ POST — создание нового объекта. Тело запроса несёт данные. Повторный POST обычно создаёт ещё один объект.
  • 🔁 PUT — замена существующего объекта целиком. Идемпотентен: повтор с теми же данными даёт тот же результат.
  • ✏️ PATCH — частичное изменение (несколько полей, не весь объект).
  • 🗑 DELETE — удаление. Тоже идемпотентен: повторное удаление уже удалённого — не ошибка.

Код состояния ответа говорит клиенту об исходе короче любого текста:

КодКогда возвращать
200Успех, в теле — результат
201Объект создан (ответ на POST)
400Клиент прислал неверные данные
401Нет авторизации или она неверна
403Авторизация есть, но прав на действие нет
404Объект или адрес не найдены
500Ошибка на стороне 1С (исключение в коде)

Не возвращайте код 200 на неуспех. Если объект не найден или данные не прошли проверку, отдавайте 404 или 400. Иначе клиент посчитает запрос успешным и продолжит работать с пустотой — такие ошибки ловятся потом неделями.

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

Опубликованный сервис доступен всем, кто знает адрес. Поэтому защита — не опция, а часть настройки.

Базовый уровень — аутентификация пользователя информационной базы. При публикации можно потребовать, чтобы клиент передавал логин и пароль через стандартный заголовок HTTP Basic (Authorization). Код в обработчике тогда выполняется от имени этого пользователя, и на него действуют обычные роли и права 1С. Это удобно: разграничение доступа к данным настраивается там же, где и для живых пользователей.

Второй приём — проверка токена в заголовке. Клиент присылает секретную строку, обработчик её сверяет:

Токен = Запрос.Заголовки.Получить("X-Auth-Token");
Если Токен = Неопределено ИЛИ Токен <> ОжидаемыйТокен() Тогда
    Возврат Новый HTTPСервисОтвет(401);
КонецЕсли;

Что ещё снижает риски:

  • 🔒 Публикуйте внешние сервисы только по HTTPS. По HTTP логин и пароль Basic-аутентификации идут практически открытым текстом и перехватываются.
  • 👤 Заведите для интеграции отдельного пользователя 1С с минимальными ролями — ровно под те справочники и регистры, с которыми работает сервис.
  • 🚦 Отдавайте наружу только то, что нужно клиенту. Не возвращайте в JSON служебные поля, GUID-ссылки и данные, которых интеграция не запрашивала.
  • 🧱 Ограничение частоты запросов и защиту от перебора удобнее вешать на веб-сервер или на reverse-proxy перед ним, а не писать в коде 1С.

Поиск причин ошибок и логирование

Когда сервис «молчит» или падает, диагностика идёт от кода ответа. Проще всего простучать сервис утилитой curl или программой вроде Postman — видно и статус, и тело, и заголовки:

curl -i -X GET "http://server/base/hs/catalog/products/000000123" -u "Интеграция:пароль"

Флаг -i покажет заголовки и код состояния, -u передаст логин и пароль Basic-аутентификации.

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

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

Для журналирования используйте штатный журнал регистрации: метод ЗаписьЖурналаРегистрации пишет в него из обработчика. Это удобно для бизнес-событий — кто и что запросил.

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

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

GET-методы тестируйте прямо в браузере: вставили адрес — увидели ответ. Это быстрый способ отделить проблему публикации (404/500 сразу) от проблемы в коде обработчика.

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

Чем HTTP-сервис отличается от web-сервиса (SOAP)?
HTTP-сервис отдаёт произвольный ответ по заданному вами адресу и работает через префикс /hs/. Web-сервис строго следует стандарту SOAP с описанием WSDL и префиксом /ws/. Для обмена с сайтами и мобильными приложениями удобнее HTTP-сервис и JSON.
Нужен ли отдельный веб-сервер или можно без него?
Веб-сервер нужен обязательно — именно он принимает входящее соединение и передаёт его платформе через модуль расширения. Подойдёт IIS или Apache. Напрямую, без публикации, HTTP-сервис вызвать нельзя.
Как передать несколько параметров в запросе?
Переменные части адреса задаются в шаблоне фигурными скобками и читаются из Запрос.ПараметрыURL. Параметры после ? в адресе доступны через Запрос.ПараметрыЗапроса. Большие наборы данных передают телом POST-запроса в JSON.
Почему сервис отвечает в браузере, но не из внешней программы?
Браузер шлёт только GET и сам подставляет авторизацию после запроса пароля. Внешняя программа должна явно передать заголовок Authorization и правильный Content-Type, а при POST — ещё и корректное тело. Сверьте заголовки через curl -i.
Можно ли вызывать HTTP-сервис из самой 1С?
Да, через объекты HTTPСоединение и HTTPЗапрос — это обратная сторона механизма, клиент на встроенном языке. Так одна база обращается к сервису другой базы или к внешнему API.