Свой REST-интерфейс для базы 1С: HTTP-сервис от шаблона URL до проверки через curl

· 9 мин

Содержание

«Загрузить API в 1С» нельзя в буквальном смысле: готового файла с API, который импортируется в базу, не бывает. API в 1С 8.3 создают сами — это объект конфигурации Общие → HTTP-сервисы, который публикуют на веб-сервере. После публикации база отвечает на запросы по адресу вида https://сервер/имя_публикации/hs/корневой_url/ресурс.

Обратная задача — забрать данные из чужого API (маркетплейса, банка, CRM) — решается не HTTP-сервисом, а объектами HTTPСоединение и HTTPЗапрос во встроенном языке. Обе стороны разобраны ниже: сначала свой сервис, затем вызов внешнего.

Подготовка: что нужно до создания HTTP-сервиса

HTTP-сервис работает только через веб-сервер. Сама платформа порт для REST-запросов не открывает, поэтому начните с инфраструктуры.

🔧 Что понадобится:

  • Веб-сервер — Apache 2.4 или IIS. Для тестов подойдёт любой, для боевой работы чаще берут Apache или IIS на отдельной машине.
  • Модули расширения веб-сервера 1С — компонент дистрибутива платформы. При установке отметьте его в списке компонентов. Разрядность модуля должна совпадать с разрядностью веб-сервера.
  • Права на изменение конфигурации. Типовую конфигурацию на поддержке лучше не снимать с замка: HTTP-сервис можно добавить в расширение конфигурации .
  • Отдельный пользователь информационной базы для интеграции, с ролью только на нужные объекты.

Расширение — самый безопасный путь для типовых БП, ЗУП и УТ. Обновление конфигурации не затронет ваш сервис, а при сбое расширение отключается одной галкой.

Где создаётся объект

  1. Откройте конфигуратор, в дереве конфигурации (или расширения) раскройте ветку Общие.
  2. Найдите HTTP-сервисы, вызовите контекстное меню и выберите «Добавить».
  3. Задайте имя, например APIЗаказы, и корневой URL — латиницей, без пробелов: orders.

Корневой URL станет частью адреса. Менять его после того, как внешние системы начали вызывать сервис, неудобно — договоритесь о нём заранее.

Шаблоны URL и методы: каркас будущего API

Внутри HTTP-сервиса два уровня: шаблоны URL (ресурсы) и методы (GET, POST, PUT, DELETE и другие) у каждого шаблона.

ШаблонМетодЧто делает
/listGETсписок заказов с фильтром
/{id}GETодин заказ по номеру
/POSTсоздание заказа
/{id}/statusPUTсмена статуса

Параметр в фигурных скобках {id} платформа вырезает из адреса сама. Звёздочка * в конце шаблона ловит любой хвост пути — пригодится для заглушки «ресурс не найден».

Обработчик метода

У каждого метода есть свойство «Обработчик». Нажмите кнопку с лупой рядом с ним — в модуле HTTP-сервиса появится функция. Она получает объект HTTPСервисЗапрос и обязана вернуть HTTPСервисОтвет.

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

	НомерЗаказа = Запрос.ПараметрыURL["id"];

	Ссылка = Документы.ЗаказКлиента.НайтиПоНомеру(НомерЗаказа);
	Если Ссылка.Пустая() Тогда
		Возврат ОтветJSON(404, Новый Структура("error", "Заказ не найден"));
	КонецЕсли;

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

	Возврат ОтветJSON(200, Данные);

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

Имя документа и реквизитов возьмите из своей конфигурации — здесь условный пример. Параметры строки запроса (?limit=50) читаются отдельно: Запрос.ПараметрыЗапроса.Получить("limit"). Если параметра нет, вернётся Неопределено, и это надо проверить до преобразования в число.

Форматы данных в API 1С: JSON и XML

Почти все современные интеграции ходят в JSON. XML остаётся для обменов с госсистемами и старыми учётными программами.

Ответ в JSON

Вынесите формирование ответа в общую функцию модуля — так код и заголовки будут одинаковыми во всех методах:

Функция ОтветJSON(КодСостояния, Данные)

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

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

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

Ссылки на объекты (документы, справочники) напрямую в JSON не записываются — ЗаписатьJSON упадёт с ошибкой. Перед записью превращайте ссылку в строку: номер, код, наименование или Строка(Ссылка.УникальныйИдентификатор()). Дата записывается в формате ISO, число — числом.

Чтение тела POST-запроса

Функция ЗаказPOST(Запрос)

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

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

	Если Данные.Получить("customer") = Неопределено Тогда
		Возврат ОтветJSON(400, Новый Структура("error", "Не указан покупатель"));
	КонецЕсли;

	// создание документа по полученным данным

	Возврат ОтветJSON(201, Новый Структура("result", "created"));

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

Второй параметр Истина у ПрочитатьJSON возвращает Соответствие вместо Структуры. Так надёжнее: ключ с дефисом или цифрой в начале не сломает чтение.

XML

Для XML используются ЧтениеXML и ЗаписьXML, а при строгой схеме — пакет XDTO. Заголовок ответа меняется на application/xml; charset=utf-8. Если внешняя система присылает XML по своей XSD-схеме, загрузите её в конфигурацию как пакет XDTO: разбор станет типизированным.

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

Пока сервис не опубликован, снаружи его не видно.

  1. Запустите конфигуратор от имени администратора Windows — без этого публикация в IIS или в каталог Apache не запишется.
  2. Откройте Администрирование → Публикация на веб-сервере.
  3. Укажите имя публикации (оно станет частью адреса), веб-сервер и каталог.
  4. На вкладке HTTP-сервисов отметьте нужные сервисы или оставьте публикацию всех по умолчанию.
  5. Нажмите «Опубликовать». Для Apache потребуется перезапуск службы веб-сервера.

Перезапуск Apache или IIS обрывает текущие сеансы веб-клиента и всех опубликованных сервисов этого сервера. Делайте его вне рабочего времени или предупредите пользователей.

В каталоге публикации появится файл default.vrd — в нём строка подключения к базе и список сервисов. На Linux публикацию делают утилитой webinst из каталога платформы: ключи для Apache и строки подключения смотрите в справке утилиты.

Итоговый адрес для примера выше:

https://srv.local/trade/hs/orders/list
https://srv.local/trade/hs/orders/000000123

Здесь trade — имя публикации, hs — постоянный сегмент для HTTP-сервисов, orders — корневой URL.

Авторизация и безопасность обмена данными

По умолчанию HTTP-сервис требует аутентификацию пользователя 1С. Внешняя система передаёт логин и пароль в заголовке Authorization: Basic … (строка логин:пароль в Base64).

🔐 Минимальный набор мер:

  • 🔒 Только HTTPS. Basic-авторизация без шифрования передаёт пароль почти открытым текстом. Сертификат настраивается на веб-сервере, не в 1С.
  • 👤 Отдельный пользователь для каждой внешней системы. Доступ одной интеграции можно закрыть, не трогая остальные.
  • 📉 Узкая роль. Пользователь видит только те справочники и документы, которые отдаёт API.
  • 🚫 Пароль в default.vrd не храните. Строка подключения позволяет вписать логин и пароль, и сервис станет открытым для всех, кто знает адрес.
  • 🌐 Ограничение по IP на веб-сервере или межсетевом экране, если партнёр работает с фиксированных адресов.

Привилегированный режим

Иногда обработчику нужны данные, на которые у интеграционного пользователя нет прав. Вызов УстановитьПривилегированныйРежим(Истина) снимает проверку прав для текущего кода. Включайте его только на узкий участок и выключайте сразу после, иначе узкая роль теряет смысл.

Повторное использование сеансов

В свойствах HTTP-сервиса есть «Режим повторного использования сеансов» и «Время жизни сеанса». Без повторного использования каждый запрос открывает новый сеанс 1С — это заметно медленнее при сотнях запросов в минуту и занимает лицензии. Режим «Автоматически использовать» держит сеанс между запросами одного клиента.

Обработка ошибок и журнал регистрации

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

Функция ЗаказPUT(Запрос)

	НачатьТранзакцию();
	Попытка
		// изменение статуса заказа
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ЗаписьЖурналаРегистрации("API.Заказы.СменаСтатуса",
			УровеньЖурналаРегистрации.Ошибка, , ,
			ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		Возврат ОтветJSON(500, Новый Структура("error", "Внутренняя ошибка, см. журнал"));
	КонецПопытки;

	Возврат ОтветJSON(200, Новый Структура("result", "ok"));

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

Коды ответа держите осмысленными — по ним партнёр решает, повторять запрос или нет:

КодКогда возвращать
200 / 201успешное чтение / создание
400неверный JSON, нет обязательного поля
401не прошла авторизация (вернёт сам веб-сервер или платформа)
404объект не найден
409конфликт, например заказ уже закрыт
500исключение внутри 1С

Журнал обменов

Журнал регистрации хорош для ошибок, но разбирать по нему спорные случаи неудобно. Для серьёзной интеграции заведите регистр сведений «Журнал API»: время, метод, адрес, код ответа, первые несколько килобайт тела запроса. Через месяц такой регистр отвечает на вопрос «а вы нам это присылали?» за минуту. Старые записи чистите регламентным заданием, иначе таблица разрастётся.

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

Тестирование и отладка HTTP-сервисов 1С

Начните с простого запроса из командной строки. curl есть в Windows 10, Windows Server 2019 и новее, а также почти в любом Linux:

curl -u api_user:Pa$$w0rd https://srv.local/trade/hs/orders/000000123

curl -u api_user:Pa$$w0rd -X POST ^
  -H "Content-Type: application/json" ^
  -d "{\"customer\":\"7701234567\",\"items\":[]}" ^
  https://srv.local/trade/hs/orders/

Ключ -i покажет заголовки ответа — удобно проверить код состояния и Content-Type. Для коллекций запросов, переменных окружения и автотестов удобнее Postman, Insomnia или встроенный HTTP-клиент среды разработки.

Отладка обработчика в конфигураторе

Точка останова в модуле HTTP-сервиса сама по себе не сработает: код выполняется в сеансе веб-сервера, а не в вашем.

  1. Включите отладку на сервере 1С (для клиент-серверной базы) — без этого конфигуратор не увидит серверные сеансы.
  2. В конфигураторе откройте Отладка → Подключение и в настройке автоматического подключения отметьте сеансы HTTP-сервисов.
  3. Для публикации разрешите отладку: в default.vrd добавляется элемент <debug enable="true" .../> с адресом сервера отладки.
  4. Поставьте точку останова и отправьте запрос через curl — выполнение остановится в обработчике.

Отладку на рабочем сервере включайте ненадолго: она замедляет работу всех сеансов. После проверки уберите элемент debug из публикации.

Обратная задача: вызов внешнего API из 1С

Если нужно не отдать данные, а получить их — например, курсы из банка или заказы с маркетплейса, — HTTP-сервис не нужен. Запрос отправляет сама 1С:

Соединение = Новый HTTPСоединение("api.example.ru", 443, , , , 30,
	Новый ЗащищенноеСоединениеOpenSSL());

Запрос = Новый HTTPЗапрос("/v1/orders?limit=100");
Запрос.Заголовки.Вставить("Authorization", "Bearer " + Токен);
Запрос.Заголовки.Вставить("Accept", "application/json");

Ответ = Соединение.Получить(Запрос);

Если Ответ.КодСостояния = 200 Тогда
	Чтение = Новый ЧтениеJSON;
	Чтение.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8));
	Заказы = ПрочитатьJSON(Чтение, Истина);
	Чтение.Закрыть();
Иначе
	ЗаписьЖурналаРегистрации("API.Маркетплейс", УровеньЖурналаРегистрации.Ошибка, , ,
		"Код ответа " + Формат(Ответ.КодСостояния, "ЧГ=0"));
КонецЕсли;

Число 30 — таймаут в секундах; без него зависший партнёр подвесит и ваш сеанс. Для POST тело задают через Запрос.УстановитьТелоИзСтроки(...), а отправляют методом Соединение.ОтправитьДляОбработки(Запрос).

💡 Практические приёмы:

  • 🔑 Токен храните не в коде модуля, а в константе или безопасном хранилище данных — так его можно сменить без выпуска новой версии.
  • ⏱ Регулярную загрузку повесьте на регламентное задание, а не на кнопку пользователя.
  • 📄 Большие списки внешние API отдают страницами: читайте в цикле, пока ответ не придёт пустым или без признака следующей страницы.
  • 🏢 Если сервер 1С выходит в интернет через прокси, передайте объект ИнтернетПрокси пятым параметром конструктора HTTPСоединение — отдельной настройки для HTTP-запросов нет.

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

Можно ли сделать API в 1С без веб-сервера?
Нет. HTTP-сервисы публикуются только через Apache или IIS с модулем расширения 1С. Альтернатива без веб-сервера — внешнее соединение через COM, но это не REST и работает только из Windows.
Чем HTTP-сервис отличается от веб-сервиса в 1С?
Веб-сервис работает по SOAP со схемой WSDL и строгими типами. HTTP-сервис — произвольные адреса и форматы, обычно REST с JSON. Для новых интеграций чаще выбирают HTTP-сервис.
Расходует ли HTTP-сервис лицензию 1С?
Да, каждый сеанс HTTP-сервиса занимает клиентскую лицензию, как обычный пользователь. Повторное использование сеансов снижает их число при частых запросах.
Есть ли в типовых конфигурациях готовый REST API?
Да, платформа умеет публиковать стандартный интерфейс OData — доступ к справочникам, документам и регистрам без программирования. Состав объектов задают в режиме предприятия, а для своей логики всё равно нужен HTTP-сервис.
Как передать файл через API 1С?
Небольшой файл передают в JSON строкой Base64. Для крупных удобнее отправлять двоичное тело целиком: в обработчике его читают методом ПолучитьТелоКакДвоичныеДанные().