Свой REST-интерфейс для базы 1С: HTTP-сервис от шаблона URL до проверки через curl
Содержание
«Загрузить 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-сервис можно добавить в расширение конфигурации .
- Отдельный пользователь информационной базы для интеграции, с ролью только на нужные объекты.
Расширение — самый безопасный путь для типовых БП, ЗУП и УТ. Обновление конфигурации не затронет ваш сервис, а при сбое расширение отключается одной галкой.
Где создаётся объект
- Откройте конфигуратор, в дереве конфигурации (или расширения) раскройте ветку
Общие. - Найдите
HTTP-сервисы, вызовите контекстное меню и выберите «Добавить». - Задайте имя, например
APIЗаказы, и корневой URL — латиницей, без пробелов:orders.
Корневой URL станет частью адреса. Менять его после того, как внешние системы начали вызывать сервис, неудобно — договоритесь о нём заранее.
Шаблоны URL и методы: каркас будущего API
Внутри HTTP-сервиса два уровня: шаблоны URL (ресурсы) и методы (GET, POST, PUT, DELETE и другие) у каждого шаблона.
| Шаблон | Метод | Что делает |
|---|---|---|
/list | GET | список заказов с фильтром |
/{id} | GET | один заказ по номеру |
/ | POST | создание заказа |
/{id}/status | PUT | смена статуса |
Параметр в фигурных скобках {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-сервисов на веб-сервере
Пока сервис не опубликован, снаружи его не видно.
- Запустите конфигуратор от имени администратора Windows — без этого публикация в IIS или в каталог Apache не запишется.
- Откройте
Администрирование → Публикация на веб-сервере. - Укажите имя публикации (оно станет частью адреса), веб-сервер и каталог.
- На вкладке HTTP-сервисов отметьте нужные сервисы или оставьте публикацию всех по умолчанию.
- Нажмите «Опубликовать». Для 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С (для клиент-серверной базы) — без этого конфигуратор не увидит серверные сеансы.
- В конфигураторе откройте
Отладка → Подключениеи в настройке автоматического подключения отметьте сеансы HTTP-сервисов. - Для публикации разрешите отладку: в
default.vrdдобавляется элемент<debug enable="true" .../>с адресом сервера отладки. - Поставьте точку останова и отправьте запрос через 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-запросов нет.