Веб-сервисы 1С: создать, опубликовать и вызвать из своего кода и чужих систем

· 9 мин

Содержание

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

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

Какой сервис вам нужен: SOAP или HTTP

В конфигураторе в дереве метаданных есть две ветки: Веб-сервисы и HTTP-сервисы. Выбор зависит от того, с кем вы обмениваетесь.

КритерийВеб-сервис (SOAP)HTTP-сервис
Формат обменаXML, строго по схемелюбой: JSON, XML, текст, файл
Описание интерфейсаавтоматически, файл WSDLвы описываете сами
Адрес в публикации…/ws/ИмяСервиса…/hs/КорневойURL/…
Когда подходитдругая система умеет читать WSDL, нужна жёсткая типизацияREST-подобный обмен, мобильные приложения, сайты
Сложность клиентавысокая вне 1С, низкая внутри 1Снизкая везде

Если на другой стороне современный сайт или мобильное приложение, берите HTTP-сервис и JSON. Если партнёр присылает WSDL или между 1С-базами нужен типизированный обмен — SOAP.

Что подготовить до создания сервиса

Три вещи, без которых публикация не получится или не будет работать:

  • 🖥 Веб-сервер. Подойдут IIS или Apache. В поставке платформы есть модуль расширения веб-сервера; при установке платформы его нужно отметить отдельным компонентом.
  • 👤 Пользователь базы. Сервис работает от имени пользователя информационной базы. Заведите отдельного технического пользователя с минимальными правами, а не отдавайте внешней системе логин администратора.
  • 🔌 Тип базы. Файловая база публикуется, но для рабочего обмена с несколькими клиентами лучше клиент-серверный вариант: веб-сервер и сервер 1С держат соединения независимо.

Платформа должна быть версии 8.3 с интерфейсом «Такси» (линейка 8.3.2x и новее), примеры ниже написаны под неё.

Как создать веб-сервис в конфигураторе

Ниже путь для SOAP-сервиса. Для HTTP-сервиса логика та же, отличается набор свойств.

  1. Откройте базу в Конфигураторе, в дереве метаданных найдите ветку Веб-сервисы, добавьте новый объект.
  2. Задайте имя (латиницей короче и безопаснее, оно попадёт в адрес) и URI пространства имён. Это строка-идентификатор, например http://example.org/orders. Она не обязана вести на реальную страницу, но должна быть уникальной.
  3. Добавьте операцию: имя, тип возвращаемого значения, параметры. Типы параметров берутся из XDTO-пакетов, самые простые — xs:string, xs:int, xs:boolean, xs:date.
  4. В свойстве операции Имя процедуры укажите обработчик. Сам код пишется в модуле веб-сервиса.

Пример обработчика, который по номеру заказа возвращает его статус:

Функция ПолучитьСтатусЗаказа(НомерЗаказа)

	Запрос = Новый Запрос;
	Запрос.Текст =
		"ВЫБРАТЬ ПЕРВЫЕ 1
		|	ЗаказПокупателя.Статус КАК Статус
		|ИЗ
		|	Документ.ЗаказПокупателя КАК ЗаказПокупателя
		|ГДЕ
		|	ЗаказПокупателя.Номер = &Номер";
	Запрос.УстановитьПараметр("Номер", НомерЗаказа);

	Выборка = Запрос.Выполнить().Выбрать();
	Если Выборка.Следующий() Тогда
		Возврат Строка(Выборка.Статус);
	КонецЕсли;

	Возврат "Заказ не найден";

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

Документ и реквизиты в вашей конфигурации могут называться иначе, подставьте свои.

Если нужен HTTP-сервис

В ветке HTTP-сервисы задаются корневой URL (например, orders), затем шаблоны URL (/status/{Номер}) и методы шаблона: GET, POST, PUT, DELETE. Обработчик получает объект HTTPСервисЗапрос и возвращает HTTPСервисОтвет:

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

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

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

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

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

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

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

В окне задайте:

  1. Имя публикации — оно станет частью адреса, например base.
  2. Веб-сервер и каталог на диске, куда запишется файл default.vrd.
  3. На вкладке сервисов отметьте нужные: веб-сервисы и/или HTTP-сервисы. Для конкретного сервиса можно включить публикацию отдельно.
  4. Нажмите Опубликовать. Если веб-сервер не обнаружен или нет прав на запись в его каталог, Конфигуратор сообщит об этом.

Файл default.vrd — это XML с настройками публикации. Его можно править руками, например, чтобы опубликовать только нужные сервисы и не открывать наружу всю базу.

Готовые адреса выглядят так:

  • WSDL SOAP-сервиса: http://сервер/base/ws/orders?wsdl
  • HTTP-сервис: http://сервер/base/hs/orders/status/1042

Сначала откройте адрес WSDL в браузере. Если вы видите XML-схему, публикация работает, и дальше можно искать ошибки только в клиенте. Если браузер вернул 404 или 500, клиент тут ни при чём.

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

Вызов веб-сервиса из другой базы 1С

Для SOAP внутри платформы работают два объекта: WSОпределения читает WSDL, WSПрокси вызывает операции.

Определения = Новый WSОпределения(
	"http://сервер/base/ws/orders?wsdl", "ТехПользователь", "Пароль");

Прокси = Новый WSПрокси(
	Определения,
	"http://example.org/orders",   // URI пространства имён
	"orders",                       // имя сервиса
	"ordersSoap");                  // точка подключения

Статус = Прокси.ПолучитьСтатусЗаказа("1042");

Имя сервиса, пространство имён и точку подключения возьмите из самого WSDL. Для точки подключения обычно используется имя сервиса с суффиксом Soap; сверьте с файлом, а не угадывайте.

Параметры, пользователь и пароль не хранятся в тексте модуля: держите их в константах или регистре сведений. Если сервис возвращает сложный тип, результат приходит как объект ОбъектXDTO, и читать его нужно через свойства: Результат.Заголовок.

Вызов HTTP-сервиса: GET и POST

Для HTTP-сервиса используйте HTTPСоединение и HTTPЗапрос:

Соединение = Новый HTTPСоединение("сервер", 80, "ТехПользователь", "Пароль");

Запрос = Новый HTTPЗапрос("/base/hs/orders/status/1042");
Ответ = Соединение.Получить(Запрос);

Если Ответ.КодСостояния = 200 Тогда
	Тело = Ответ.ПолучитьТелоКакСтроку();
Иначе
	ВызватьИсключение "Сервис вернул код " + Ответ.КодСостояния;
КонецЕсли;

Для отправки данных используйте Отправить (POST) и задайте тело и заголовок:

Запрос = Новый HTTPЗапрос("/base/hs/orders/new");
Запрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Запрос.УстановитьТелоИзСтроки("{""клиент"": ""ООО Ромашка"", ""сумма"": 12500}");

Ответ = Соединение.ОтправитьДляОбработки(Запрос);

Если у вас HTTPS, вместо порта 80 создавайте соединение с защищённым транспортом: параметр ЗащищенноеСоединение (в свойствах соединения задаётся объектом ЗащищенноеСоединениеOpenSSL). Для внутреннего самоподписанного сертификата добавьте его в доверенные на машине, где работает клиент, а не отключайте проверку.

Вызов из внешней системы

Любой клиент, который умеет HTTP, обращается к тому же адресу. Проверить вручную можно утилитой curl:

curl -u ТехПользователь:Пароль http://сервер/base/hs/orders/status/1042

Для SOAP-клиентов (Java, .NET, Python) достаточно передать адрес WSDL генератору кода: он построит заглушки сам.

Аутентификация и защита канала

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

Практика, которая закрывает 90% рисков:

  • 🔒 Отдельный технический пользователь с ролью, где разрешены только нужные объекты.
  • 🔒 HTTPS на внешнем адресе, сертификат от доверенного центра.
  • 🔒 В default.vrd опубликованы только нужные сервисы, остальные отключены.
  • 🔒 Доступ к адресу ограничен по IP на уровне веб-сервера или межсетевого экрана.
  • 🔒 Для сервисов в доменной сети можно включить аутентификацию средствами ОС, тогда пароль в запросе не нужен.

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

Разбор JSON в ответе и в запросе

HTTP-сервис почти всегда обменивается JSON. Читать его строкой и резать подстроками не нужно, в платформе есть ЧтениеJSON и ЗаписьJSON.

Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
Данные = ПрочитатьJSON(Чтение, Истина);   // Истина: объекты JSON станут соответствиями
Чтение.Закрыть();

Статус = Данные.Получить("статус");

Для ответа сделайте наоборот: заполните Структуру или Соответствие и сериализуйте через ЗаписьJSON и ЗаписатьJSON. Так кавычки и спецсимволы в значениях экранируются сами, чего не скажешь о ручной склейке строк из примера выше. Её оставили ради наглядности, в рабочем коде собирайте ответ через ЗаписьJSON.

Когда веб-сервис не нужен

Обмен через сервис оправдан, когда данные нужны сразу и по одной записи или небольшими порциями. Для остальных случаев есть варианты проще:

  • 📦 разовая выгрузка большого справочника — файл и обмен через общую папку;
  • 📦 две базы на одной конфигурации и стандартный обмен — готовые правила обмена данными;
  • 📦 данные нужны раз в сутки — регламентное задание, которое кладёт файл в нужное место.

Сервис требует публикации, учёта прав, мониторинга и поддержки версий интерфейса. Если вы не готовы это сопровождать, возьмите простое решение.

Ошибки и отладка

Сначала определите, на каком участке цепочки ломается запрос: сеть, веб-сервер, платформа, ваш код.

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

Как отлаживать:

  1. Проверьте адрес из браузера на той же машине, где работает клиент.
  2. Для обработчика запускайте отладку из Конфигуратора: сервис можно отлаживать как обычный серверный код, если подключён отладчик к серверу.
  3. Если непонятно, что реально уходит по сети, поставьте между клиентом и сервисом перехватчик HTTP (Fiddler, Wireshark, прокси) и посмотрите запрос и ответ целиком.
  4. Логируйте вход и выход обработчика в журнал регистрации: ЗаписьЖурналаРегистрации("Сервис.Заказы", УровеньЖурналаРегистрации.Информация, , , Номер).

Скорость: что тормозит и как ускорить

Чаще всего медленным оказывается не сам вызов, а то, что за ним стоит.

  • ⏱ Повторный запуск сеанса. Каждый новый запрос по умолчанию может поднимать сеанс базы заново. Для частых вызовов настройте в default.vrd повторное использование сеансов (атрибут reuseSessions); подробности и допустимые значения сверьте с документацией платформы.
  • ⏱ Пакетная работа вместо цикла. Не вызывайте сервис по одной записи из цикла на сотни элементов. Сделайте операцию, которая принимает массив и отвечает один раз.
  • ⏱ Тяжёлые запросы. Обработчик, который в цикле ходит в базу за каждой строкой, лучше заменить одним запросом с соединением таблиц.
  • ⏱ Размер ответа. Отдавайте только нужные поля. Для больших выгрузок используйте постраничную выдачу.
  • ⏱ Блокировки. Если сервис пишет данные, держите транзакцию короткой, иначе пользователи в базе упрутся в блокировки.
Прежде чем отдавать адрес партнёру
Выполнено: 0 / 5

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

Можно ли вызывать веб-сервис 1С из Excel или Python?
Да. HTTP-сервис вызывается обычным запросом (в Python — библиотека requests). SOAP-сервис читается по адресу WSDL любым SOAP-клиентом.
Чем отличается `ОтправитьДляОбработки` от `Получить`?
Получить делает GET без тела. ОтправитьДляОбработки выполняет POST с телом, а метод ВызватьHTTPМетод позволяет указать любой метод, например PUT или DELETE.
Нужно ли открывать для сервиса порт 1541?
Нет. Клиент обращается к веб-серверу по 80 или 443, а веб-сервер сам соединяется с кластером 1С.
Можно ли опубликовать сервис без Конфигуратора?
Да. Файл default.vrd можно создать вручную или утилитой командной строки платформы, а затем положить в каталог веб-сервера. Параметры утилиты смотрите в её справке.
Работает ли сервис, если пользователь забыл закрыть базу в Конфигураторе?
Как правило, да: обычная работа сервисов монопольного доступа не требует. Он нужен только при операциях вроде обновления структуры базы.