HTTP-сервисы в 1С: от объекта конфигурации до первого ответа
Содержание
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-сервисы.
- HTTP-сервис. Верхний объект. Его главное свойство —
Корневой URL: короткое имя, которое встанет в адрес после/hs/. Например, корневой URLcatalogдаёт базовую ссылку.../hs/catalog. - Шаблон URL. Описывает путь внутри сервиса. В шаблоне можно задать переменные части в фигурных скобках:
/products/{id}. Значение из адреса потом доступно в коде. - Метод. Привязан к шаблону. У метода есть свойство
HTTP-метод(GET, POST, PUT, DELETE и другие) и свойствоИмя обработчика— имя функции в модуле сервиса.
Один шаблон обычно держит несколько методов: GET на /products/{id} отдаёт товар, DELETE на том же шаблоне его удаляет. Платформа сама выберет нужный метод по глаголу запроса.
Весь код живёт в модуле HTTP-сервиса. Открывается он так же, как модуль любого объекта, — через контекстное меню в дереве конфигурации.
Публикация на веб-сервере и сборка адреса
Пока сервис не опубликован, вызвать его нельзя. Публикация выполняется из конфигуратора: Администрирование → Публикация на веб-сервере….
В окне публикации:
- Задайте имя — оно станет частью адреса (
http://сервер/имя/...) и именем каталога на диске. - Укажите каталог, куда положить файлы публикации, и выберите веб-сервер.
- Перейдите на вкладку HTTP-сервисы и отметьте флажками те сервисы, которые нужно опубликовать.
- Нажмите Опубликовать.
Платформа создаст в каталоге файл default.vrd — это описание публикации. В нём среди прочего перечислены включённые HTTP-сервисы. Если позже понадобится открыть ещё один сервис, проще заново пройти диалог публикации, чем править файл руками.
После этого адрес собирается по схеме:
http://<сервер>/<имя публикации>/hs/<корневой URL>/<путь из шаблона>
Для корневого URL catalog и шаблона /products/{id} полный GET-адрес выглядит так:
http://server/base/hs/catalog/products/000000123
Фрагмент 000000123 попадёт в переменную id шаблона.
Модуль расширения веб-сервера должен совпадать по разрядности с веб-сервером (x86/x64) и быть той же версии, что и платформа. Несовпадение даёт ошибку 500 или пустую страницу ещё до того, как выполнится хоть одна строка вашего кода.
Код обработчика: разбираем запрос и собираем ответ
Обработчик — это функция, которая принимает один параметр (запрос) и возвращает объект ответа. Имя функции вы указали в свойстве метода.
Из входящего запроса доступны:
Запрос.Параметры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.
Таблица поможет выбрать формат:
| Критерий | JSON | XML |
|---|---|---|
| Объём тела | компактнее | тяжелее |
| Поддержка в вебе и мобильных | по умолчанию | реже |
| Строгая схема и валидация | слабая | сильная (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-аутентификации.
Разобраться в типичных симптомах помогает таблица ниже.
/hs/ вместо /ws/), опечатка в корневом URL или шаблоне. Переопубликуйте и сверьте адрес посимвольно.Authorization и роли пользователя интеграции.Попытка … Исключение и верните понятный код.Content-Type с charset=utf-8 в заголовках ответа. Добавьте заголовок.Для журналирования используйте штатный журнал регистрации: метод ЗаписьЖурналаРегистрации пишет в него из обработчика. Это удобно для бизнес-событий — кто и что запросил.
Для низкоуровневой диагностики (само обращение к веб-серверу, старт сеанса) включают технологический журнал через файл logcfg.xml. Он тяжёлый и подробный, поэтому держать его постоянно включённым на боевой базе не стоит — включили, воспроизвели проблему, выключили.
Полезный приём при разработке — временно возвращать клиенту текст ошибки в теле ответа с кодом 500. На время отладки это экономит заходы в журнал, но перед выводом сервиса в работу текст исключения из ответа уберите: наружу не должны утекать внутренние сообщения платформы и структура базы. В бою клиент получает только код состояния и нейтральное описание, а подробности остаются в журнале регистрации.
GET-методы тестируйте прямо в браузере: вставили адрес — увидели ответ. Это быстрый способ отделить проблему публикации (404/500 сразу) от проблемы в коде обработчика.
Частые вопросы
Чем HTTP-сервис отличается от web-сервиса (SOAP)?
/hs/. Web-сервис строго следует стандарту SOAP с описанием WSDL и префиксом /ws/. Для обмена с сайтами и мобильными приложениями удобнее HTTP-сервис и JSON.Нужен ли отдельный веб-сервер или можно без него?
Как передать несколько параметров в запросе?
Запрос.ПараметрыURL. Параметры после ? в адресе доступны через Запрос.ПараметрыЗапроса. Большие наборы данных передают телом POST-запроса в JSON.Почему сервис отвечает в браузере, но не из внешней программы?
Authorization и правильный Content-Type, а при POST — ещё и корректное тело. Сверьте заголовки через curl -i.Можно ли вызывать HTTP-сервис из самой 1С?
HTTPСоединение и HTTPЗапрос — это обратная сторона механизма, клиент на встроенном языке. Так одна база обращается к сервису другой базы или к внешнему API.