HTTP-сервис в 1С 8.3 от пустой ветки до рабочего API
Содержание
Веб-сервис в 1С 8.3 создают в конфигураторе: ветка Общие → HTTP-сервисы (REST) или Общие → Web-сервисы (SOAP). Добавляете сервис, задаёте корневой URL и шаблон адреса, пишете функцию-обработчик метода и публикуете базу на веб-сервере. После этого сервис отвечает по адресу вида http://сервер/база/hs/корневой-url/шаблон.
Внешняя система стучится в базу, а вы не знаете, с какой стороны браться? Хватит одного рабочего дня: объект метаданных, два обработчика, публикация и проверка через curl.
Какой сервис выбрать: HTTP или SOAP
В платформе два механизма. Оба живут в ветке Общие дерева метаданных и оба публикуются через веб-сервер.
| HTTP-сервис | Web-сервис (SOAP) | |
|---|---|---|
| Протокол | обычный HTTP, любой формат тела | SOAP поверх HTTP, XML |
| Формат данных | JSON, XML, текст, файлы — на ваше усмотрение | XML по схеме XDTO-пакета |
| Описание для клиента | пишете сами | WSDL генерируется автоматически |
| Адрес в публикации | /hs/ | /ws/ |
| Когда брать | сайты, мобильные приложения, интеграции на JSON | банки, госсистемы, старые интеграции, где SOAP задан требованием |
HTTP-сервисы появились в платформе 8.3.5. Сегодня почти все новые интеграции делают на них: сайт или маркетплейс-коннектор ждёт JSON, а не SOAP-конверт.
💡 Если партнёр прислал WSDL и просит «поднять веб-сервис по этой схеме» — нужен именно SOAP. Во всех остальных случаях начинайте с HTTP-сервиса.
Как устроен запрос к HTTP-сервису
Путь запроса проходит четыре звена:
- 🌐 Клиент отправляет запрос на веб-сервер (IIS или Apache).
- 🔌 Модуль расширения веб-сервера 1С принимает его и находит публикацию по имени (
/база/). - 🔑 Платформа аутентифицирует пользователя информационной базы и открывает сеанс.
- ⚙️ По корневому URL и шаблону выбирается метод, вызывается его функция в модуле сервиса. Функция возвращает объект
HTTPСервисОтвет.
Весь код обработчика выполняется на сервере 1С с правами того пользователя, под которым пришёл запрос. От этого зависят и безопасность, и многие ошибки 500.
Создание HTTP-сервиса в конфигураторе
Работаем в конфигураторе с правами на изменение конфигурации. Если база на поддержке, удобнее вынести сервис в расширение: HTTP-сервисы можно добавлять в расширения, и обновления типовой конфигурации его не затронут.
Шаг 1. Объект и корневой URL
- В дереве метаданных раскройте
Общие, щёлкните правой кнопкой поHTTP-сервисы→Добавить. - Задайте Имя — например,
Заказы. - Заполните Корневой URL — латиницей, без пробелов:
orders.
Корневой URL — первая часть адреса после /hs/. Имя объекта в адрес не попадает, поэтому его можно писать по-русски.
Шаг 2. Шаблоны URL
На вкладке шаблонов добавьте адреса, которые сервис будет обслуживать:
/— список заказов;/{number}— один заказ, гдеnumber— параметр;/*— «всё остальное», удобно для собственного разбора пути.
Параметр в фигурных скобках платформа извлекает сама. В коде он доступен через Запрос.ПараметрыURL["number"].
Шаг 3. Методы
Внутри каждого шаблона добавьте методы — GET, POST, PUT, DELETE и другие. Для каждого метода в свойстве Обработчик нажмите лупу: платформа создаст в модуле сервиса пустую функцию с параметром Запрос.
В нашем примере:
- шаблон
/{number}, методGET— получить заказ; - шаблон
/, методPOST— создать заказ.
Шаг 4. Свойства сеанса
У объекта сервиса есть ещё два свойства, о которых часто забывают:
- Повторное использование сеансов —
Не использовать,ИспользоватьилиАвтоматически. При частых коротких запросах повторное использование экономит время на открытие сеанса. - Время жизни сеанса — сколько секунд держать неиспользуемый сеанс.
Каждый живой сеанс HTTP-сервиса занимает лицензию, как обычный пользователь. Большое время жизни при всплеске запросов быстро съедает пул лицензий.
Обработчики запросов: код GET и POST
Функция-обработчик получает объект HTTPСервисЗапрос и обязана вернуть HTTPСервисОтвет. Из запроса вы берёте всё, что прислал клиент.
| Что нужно | Как получить |
|---|---|
Параметр из шаблона {number} | Запрос.ПараметрыURL["number"] |
Параметр строки ?status=new | Запрос.ПараметрыЗапроса.Получить("status") |
| Заголовок | Запрос.Заголовки.Получить("Content-Type") |
| Тело как текст | Запрос.ПолучитьТелоКакСтроку() |
| Тело как файл | Запрос.ПолучитьТелоКакДвоичныеДанные() |
| HTTP-метод | Запрос.HTTPМетод |
ПараметрыЗапроса.Получить() возвращает Неопределено, если параметра нет. Проверяйте это до использования, иначе первый же запрос без параметра упадёт с ошибкой 500.
Метод GET: отдать заказ по номеру
Название документа и реквизитов у вас может быть другим — подставьте свои.
Функция ЗаказGET(Запрос)
Номер = Запрос.ПараметрыURL["number"];
ЗапросДанных = Новый Запрос(
"ВЫБРАТЬ ПЕРВЫЕ 1
| Заказ.Номер КАК Номер,
| Заказ.Дата КАК Дата,
| Заказ.СуммаДокумента КАК Сумма
|ИЗ
| Документ.ЗаказКлиента КАК Заказ
|ГДЕ
| Заказ.Номер = &Номер");
ЗапросДанных.УстановитьПараметр("Номер", Номер);
Выборка = ЗапросДанных.Выполнить().Выбрать();
Если Не Выборка.Следующий() Тогда
Возврат ОтветJSON(404, Новый Структура("error", "Заказ не найден"));
КонецЕсли;
Данные = Новый Структура;
Данные.Вставить("number", Выборка.Номер);
Данные.Вставить("date", Выборка.Дата);
Данные.Вставить("sum", Выборка.Сумма);
Возврат ОтветJSON(200, Данные);
КонецФункции
Переменная называется ЗапросДанных, а не Запрос: имя Запрос уже занято параметром функции. Это частая причина странных ошибок у тех, кто пишет первый сервис.
Общая функция ответа
Чтобы не повторять одни и те же пять строк в каждом методе, вынесите сборку ответа в отдельную функцию модуля:
Функция ОтветJSON(КодСостояния, Данные)
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
Настройки = Новый НастройкиСериализацииJSON;
Настройки.ФорматСериализацииДаты = ФорматДатыJSON.ISO;
ЗаписатьJSON(Запись, Данные, Настройки);
Ответ = Новый HTTPСервисОтвет(КодСостояния);
Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Ответ.УстановитьТелоИзСтроки(Запись.Закрыть(), КодировкаТекста.UTF8,
ИспользованиеByteOrderMark.НеИспользовать);
Возврат Ответ;
КонецФункции
Два приёма здесь спасают от типичных жалоб клиента:
- 💡
charset=utf-8в заголовке — без него кириллица у части клиентов превращается в «кракозябры». - 💡
ИспользованиеByteOrderMark.НеИспользовать— без явного запрета в начало тела может попасть метка BOM, и строгие JSON-парсеры (например, в PHP) отказываются разбирать ответ.
Метод POST: принять данные
Функция ЗаказыPOST(Запрос)
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(Запрос.ПолучитьТелоКакСтроку());
Попытка
Данные = ПрочитатьJSON(Чтение, Истина, "date", ФорматДатыJSON.ISO);
Исключение
Возврат ОтветJSON(400, Новый Структура("error", "Некорректный JSON"));
КонецПопытки;
Чтение.Закрыть();
Клиент = Данные.Получить("client");
Если Клиент = Неопределено Тогда
Возврат ОтветJSON(400, Новый Структура("error", "Не указан client"));
КонецЕсли;
// здесь создание и запись документа
Возврат ОтветJSON(201, Новый Структура("result", "created"));
КонецФункции
Второй параметр Истина читает объекты JSON в Соответствие, а не в Структуру. Так безопаснее: ключи вида order-id или 1c недопустимы как имена полей структуры, и чтение без этого флага упадёт.
Третий и четвёртый параметры говорят платформе, что поле date нужно сразу превратить в тип Дата из формата ISO.
JSON в 1С: как типы превращаются в текст и обратно
ЗаписатьJSON понимает только примитивы и коллекции. Ссылку на справочник или документ «как есть» он не запишет — будет исключение.
| Тип 1С | В JSON | Комментарий |
|---|---|---|
| Строка | "текст" | |
| Число | 1250.5 | дробная часть через точку |
| Булево | true / false | |
| Дата | "2026-10-07T12:00:00" | только с НастройкиСериализацииJSON, иначе исключение |
| Неопределено | null | |
| Структура, Соответствие | объект {} | у соответствия ключи должны быть строками |
| Массив | массив [] | |
| Ссылка на объект | — | передавайте код, номер или Строка(Ссылка.УникальныйИдентификатор()) |
Ссылки и идентификаторы
Самый надёжный ключ для связи с внешней системой — уникальный идентификатор объекта. Он не меняется при перенумерации и одинаков во всех копиях базы.
- 📤 Отдать:
Строка(Ссылка.УникальныйИдентификатор()). - 📥 Найти по присланному:
Справочники.Контрагенты.ПолучитьСсылку(Новый УникальныйИдентификатор(Строка)).
Ссылку, полученную через ПолучитьСсылку, проверьте на существование объекта: метод вернёт ссылку и на несуществующий объект, ошибка вылезет позже, при обращении к реквизитам.
Сериализация XDTO, если нужен объект целиком
Когда нужно выгрузить документ со всеми табличными частями «один в один» для другой базы 1С, используйте СериализаторXDTO.ЗаписатьJSON(Запись, Объект). Получится JSON в формате платформы, громоздкий, но без ручного перечисления полей. Для внешних систем он неудобен — им отдавайте собственную структуру, как в примере выше.
Публикация базы на веб-сервере
Пока база не опубликована, сервис существует только в метаданных. Для публикации нужны:
- 🖥️ веб-сервер — IIS на Windows или Apache 2.4;
- 🔌 модули расширения веб-сервера — компонент ставится из дистрибутива платформы той же разрядности, что и веб-сервер;
- 🔐 конфигуратор, запущенный от имени администратора Windows — иначе он не сможет записать настройки веб-сервера.
Публикация из конфигуратора
- Меню
Администрирование → Публикация на веб-сервере. - Укажите Имя публикации — это часть адреса, например
trade. - Выберите веб-сервер и каталог публикации.
- На вкладке HTTP-сервисов отметьте флаг публикации по умолчанию или конкретные сервисы.
- Нажмите
Опубликовать. Для Apache после этого перезапустите службу веб-сервера.
Перезапуск Apache или пула IIS обрывает все текущие веб-сеансы этого сервера: веб-клиент, другие сервисы, мобильные приложения. Делайте это вне рабочего пика.
Публикация командой webinst
На сервере без графического интерфейса или в скрипте развёртывания используйте утилиту webinst из каталога bin платформы:
webinst -publish -apache24 -wsdir trade -dir "C:\Apache24\htdocs\trade" ^
-connstr "Srvr=app-srv;Ref=trade;" -confpath "C:\Apache24\conf\httpd.conf"
Для IIS вместо -apache24 указывают -iis, параметр -confpath не нужен. Подробности по ключам — в выводе webinst без параметров.
Итоговый адрес и проверка
Адрес собирается из трёх частей:
http://сервер/trade/hs/orders/000000123
│ │ │ └─ параметр шаблона {number}
│ │ └──────── корневой URL сервиса
│ └───────────── имя публикации
└──────────────────── веб-сервер
Проверьте ответ из командной строки:
curl -u Integration:Пароль http://сервер/trade/hs/orders/000000123
Публикация хранится в файле default.vrd в каталоге публикации. После изменения конфигурации публиковать заново не нужно — достаточно обновить конфигурацию
базы данных. Повторная публикация нужна, если вы добавили новый сервис, а публикуются только отмеченные вручную.
Права и безопасность HTTP-сервиса
Сервис открывает базу наружу. Ошибка в настройке доступа — это утечка данных, а не просто неудобство.
Отдельный пользователь под интеграцию
- 👤 Заведите в базе пользователя только для интеграции, например
Integration, с аутентификацией 1С:Предприятия. - 🎭 Дайте ему роль, в которой есть права только на нужные объекты: чтение заказов, добавление документов — и ничего больше.
- 🚫 Не давайте этой учётной записи полные права и не запускайте под ней интерактивный клиент.
Клиент передаёт логин и пароль в заголовке Authorization по схеме Basic. Если пользователя нет или пароль неверный, веб-сервер вернёт 401.
HTTPS обязателен
Basic-аутентификация пересылает пароль в кодировке Base64 — это не шифрование. По голому HTTP пароль читается из трафика.
Публикуйте сервис наружу только по HTTPS. Сертификат настраивается на стороне веб-сервера, сама 1С в этом не участвует.
Чего не делать
- ❌ Не прописывайте логин и пароль в строке соединения публикации (
Usr=,Pwd=) ради «анонимного» доступа: тогда сервис открыт любому, кто узнал адрес. - ❌ Не включайте
УстановитьПривилегированныйРежим(Истина)в обработчике целиком. Привилегированный режим нужен точечно — например, чтобы записать служебный регистр, — и его надо выключать сразу после этого. - ❌ Не собирайте текст запроса склейкой строк из параметров URL. Используйте
УстановитьПараметр, как в примере GET: это закрывает подстановку чужого кода в запрос.
💡 Если наружу смотрит только один сервис, создайте под него отдельную публикацию, где отмечен только он. Веб-клиент и остальные сервисы тогда снаружи просто не видны.
Отладка и диагностика HTTP-запросов
Обработчик выполняется на сервере, поэтому точку останова в модуле сервиса просто так не поймать. Нужно подключить отладку к сеансам HTTP-сервисов.
Отладка в конфигураторе
- Включите отладку в публикации: в файле
default.vrdдобавьте элемент<debug enable="true" protocol="tcp" url="tcp://имя-компьютера-с-конфигуратором"/>или включите отладку в окне публикации, если ваша версия платформы это показывает. - В конфигураторе откройте
Отладка → Подключение, нажмитеАвтоматическое подключениеи отметьте HTTP-сервисы. - Поставьте точку останова в функции-обработчике и отправьте запрос через
curlили Postman.
Конфигуратор остановится на точке, и можно смотреть содержимое Запрос: заголовки, параметры, тело.
Не оставляйте отладку включённой в рабочей публикации: каждый запрос пытается подключиться к отладчику, что замедляет ответы.
Журнал регистрации
В рабочей базе отладчик не подключишь. Пишите ключевые события в журнал:
ЗаписьЖурналаРегистрации("HTTPСервис.Заказы",
УровеньЖурналаРегистрации.Ошибка, , ,
"Не удалось записать заказ: " + ОписаниеОшибки());
Потом фильтруйте журнал по этому событию — увидите, кто, когда и с каким текстом ошибки обращался. Код вызывается внутри блока Исключение, иначе ОписаниеОшибки() вернёт пустую строку.
Что означает код ответа
Если нужен SOAP-вариант
Для Web-сервиса порядок похож, но вместо шаблонов URL — операции с типами параметров из XDTO-пакета:
- Создайте XDTO-пакет (
Общие → XDTO-пакеты) с типами данных или используйте стандартные типы из пространства имён XML Schema. - В
Общие → Web-сервисыдобавьте сервис, укажите Пространство имён URI и список XDTO-пакетов. - Добавьте операции, параметры и тип возвращаемого значения, создайте процедуры-обработчики.
- Опубликуйте на вкладке Web-сервисов. Описание для клиента будет доступно по адресу
http://сервер/база/ws/имя?wsdl.