Свой REST API на базе 1С: от шаблона URL до рабочего запроса
Содержание
Чтобы запустить HTTP-сервис в 1С 8.3, нужны три шага: создать объект в ветке Общие → HTTP-сервисы Конфигуратора и написать обработчик, опубликовать базу на веб-сервере (Apache или IIS) с включёнными HTTP-сервисами и обратиться к адресу вида http://сервер/база/hs/корневой_URL/шаблон. Без публикации на веб-сервере сервис работать не будет: сама платформа порты для внешних клиентов не открывает.
Выбор веб-сервера зависит от инфраструктуры. На Windows с готовым IIS проще остаться на нём. Для Linux и для серверов, смотрящих в интернет, обычно берут Apache 2.4, а снаружи ставят Nginx с TLS. Для разработки и тестов хватит автономного сервера ibsrv без всякого веб-сервера.
Что даёт HTTP-сервис и когда он лучше веб-сервиса
HTTP-сервис — это объект конфигурации, который принимает обычные HTTP-запросы и возвращает ответ, собранный кодом на встроенном языке. Он появился в платформе 8.3.5. По сути, это способ сделать из базы 1С REST API.
Чем он отличается от других способов интеграции:
| Способ | Формат обмена | Когда выбирают |
|---|---|---|
| HTTP-сервис | Любой: JSON, XML, файл, текст | Сайт, мобильное приложение, бот, вебхуки — нужен свой простой API |
| Веб-сервис (SOAP) | XML по WSDL | Партнёр требует SOAP, есть готовая WSDL-схема |
| OData (стандартный интерфейс) | JSON/Atom по протоколу OData | Нужно читать и писать объекты базы без программирования |
| COM-соединение | Объекты 1С напрямую | Обмен внутри одной Windows-сети, скрипты на сервере |
Сильные стороны HTTP-сервиса:
- 🔹 вы сами решаете, какие URL, методы и поля отдать наружу;
- 🔹 клиенту не нужны библиотеки 1С: подойдёт
curl, Python, JavaScript, PHP; - 🔹 легко принимать вебхуки от платёжных систем, маркетплейсов и CRM;
- 🔹 бизнес-логика остаётся в 1С, а не дублируется в интеграции.
Цена свободы — всё нужно описать самому: формат ответа, коды ошибок, проверку входных данных.
Создание HTTP-сервиса в Конфигураторе
Работать удобнее в расширении конфигурации, если база типовая и на поддержке. Тогда обновления не затрут ваш API. Если конфигурация собственная, добавляйте объект прямо в неё.
Шаг 1. Объект и корневой URL
- Откройте Конфигуратор, дерево конфигурации, ветку
Общие → HTTP-сервисы. - Добавьте новый элемент, задайте имя, например
API. - В свойствах укажите Корневой URL:
api. Это часть адреса после/hs/.
Там же находятся свойства Повторное использование сеансов и Время жизни сеанса. К ним вернёмся в разделе про производительность.
Шаг 2. Шаблон URL и методы
Шаблон описывает путь внутри сервиса. Переменные части берутся в фигурные скобки:
/stock/{article}— остаток по артикулу;/orders— список заказов или создание нового;/orders/{id}— один заказ.
Внутри шаблона добавьте методы и выберите HTTP-метод: GET, POST, PUT, DELETE и другие. Для каждого метода задайте процедуру-обработчик. Платформа предложит имя вида StockGET и создаст функцию в модуле сервиса.
Шаг 3. Код обработчика
Обработчик получает объект HTTPСервисЗапрос и обязан вернуть HTTPСервисОтвет. Пример для GET /stock/{article}, который ищет товар по артикулу и отдаёт JSON:
Функция StockGET(Запрос)
Артикул = Запрос.ПараметрыURL.Получить("article");
Запрос1С = Новый Запрос;
Запрос1С.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Артикул = &Артикул
| И НЕ Номенклатура.ПометкаУдаления";
Запрос1С.УстановитьПараметр("Артикул", Артикул);
Выборка = Запрос1С.Выполнить().Выбрать();
Если Не Выборка.Следующий() Тогда
Возврат ОтветJSON(404, Новый Структура("error", "Товар не найден"));
КонецЕсли;
Данные = Новый Структура;
Данные.Вставить("article", Артикул);
Данные.Вставить("name", Выборка.Наименование);
Возврат ОтветJSON(200, Данные);
КонецФункции
Функция ОтветJSON(КодСостояния, Данные)
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, Данные);
Текст = Запись.Закрыть();
Ответ = Новый HTTPСервисОтвет(КодСостояния);
Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Ответ.УстановитьТелоИзСтроки(Текст, КодировкаТекста.UTF8);
Возврат Ответ;
КонецФункции
Тело POST-запроса читают так:
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(Запрос.ПолучитьТелоКакСтроку());
Входные = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
Что ещё есть у объекта запроса:
Запрос.HTTPМетод— метод, если один обработчик обслуживает несколько;Запрос.ПараметрыЗапроса— параметры после?, например?limit=50;Запрос.Заголовки— заголовки, включая ваш собственный токен;Запрос.ПолучитьТелоКакДвоичныеДанные()— для файлов.
Заворачивайте основной код в Попытка … Исключение и возвращайте 500 с понятным текстом. Иначе клиент получит голую ошибку веб-расширения, а вы — пустой журнал.
Публикация базы: Apache, IIS, Nginx и автономный сервер
Сравнение вариантов:
| Вариант | Платформа ОС | Когда подходит | Нюанс |
|---|---|---|---|
| Apache 2.4 | Windows, Linux | Основной выбор для продакшена | Разрядность Apache и модуля 1С должна совпадать |
| IIS | Windows Server | Уже есть IIS, домен Windows | Нужны компоненты ISAPI и CGI |
| Nginx | Linux, Windows | Только как прокси перед Apache или IIS | Модуля 1С для Nginx нет |
Автономный сервер ibsrv | Windows, Linux | Разработка, тесты, небольшие файловые базы | Появился в 8.3.14, без кластера |
На компьютере, где стоит веб-сервер, должны быть установлены модули расширения веб-сервера той же версии, что и платформа. Их выбирают при установке платформы.
Публикация из Конфигуратора
- Запустите Конфигуратор от имени администратора ОС.
- Откройте
Администрирование → Публикация на веб-сервере. - Задайте Имя публикации, например
trade. Оно станет частью адреса. - Выберите веб-сервер и каталог публикации.
- На вкладке HTTP-сервисов отметьте флажок публикации по умолчанию или выберите нужные сервисы по одному.
- Нажмите Опубликовать. Для Apache согласитесь на перезапуск.
Готовый адрес: http://имя-сервера/trade/hs/api/stock/A-100.
Публикация утилитой webinst
На сервере без графического Конфигуратора удобнее командная строка. Утилита лежит в каталоге bin платформы:
webinst -publish -apache24 -wsdir trade -dir "C:\www\trade" -connstr "Srvr=srv1c;Ref=trade;" -confpath "C:\Apache24\conf\httpd.conf"
Для IIS вместо -apache24 и -confpath укажите -iis. Утилита создаёт в каталоге публикации файл default.vrd. Именно он определяет, какие сервисы видны снаружи:
<point xmlns="http://v8.1c.ru/8.2/virtual-resource-system"
base="/trade" ib="Srvr=srv1c;Ref=trade;">
<httpServices publishByDefault="false">
<service name="API" rootUrl="api" enable="true"
reuseSessions="autouse" sessionMaxAge="20"
poolSize="10" poolTimeout="5"/>
</httpServices>
</point>
После правки default.vrd перезапустите веб-сервер, иначе изменения не подхватятся. Перезапуск оборвёт текущие запросы через веб-клиент и сервисы, поэтому делайте его в спокойное время.
Nginx перед Apache
Nginx удобно ставить на внешний контур: он принимает HTTPS, держит сертификат и передаёт запрос Apache на внутренний порт:
location /trade/hs/ {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 300s;
}
Публикуйте наружу только путь /hs/, а не всю базу целиком. Тогда веб-клиент и OData останутся недоступны из интернета.
Авторизация и защита API
По умолчанию HTTP-сервис требует аутентификацию пользователем 1С. Клиент передаёт заголовок Authorization: Basic … с логином и паролем в Base64. Учётную запись лучше завести отдельную, например api_site, с ролью только на нужные данные.
Варианты доступа:
- 🔐 Basic-авторизация пользователем 1С — стандартный путь, работает сразу;
- 🔐 аутентификация ОС — для клиентов внутри домена Windows;
- 🔐 логин и пароль в строке соединения
default.vrd(Usr=…;Pwd=…) — все запросы идут под одним пользователем без авторизации со стороны клиента.
Третий вариант открывает сервис любому, кто знает адрес. Используйте его только с собственной проверкой: токен в заголовке, который обработчик сверяет с константой или регистром сведений, и белый список IP на Nginx.
Минимальный набор защиты для сервиса в интернете:
- Только HTTPS. Basic-авторизация по открытому HTTP передаёт пароль почти открытым текстом.
- У технического пользователя нет интерактивных ролей и права администрирования.
- Обработчик проверяет входные данные: тип, длину, допустимые значения.
- Привилегированный режим включайте точечно и только там, где без него не обойтись.
- На Nginx задан лимит частоты запросов (
limit_req), чтобы один клиент не положил базу.
Проверка и отладка HTTP-сервиса
Сначала проверьте сервис снаружи. Для этого хватит curl:
curl -u api_site:пароль "http://srv/trade/hs/api/stock/A-100"
curl -u api_site:пароль -X POST -H "Content-Type: application/json" -d "{\"number\":\"123\"}" "http://srv/trade/hs/api/orders"
Удобнее работать в Postman или Insomnia: там сохраняются запросы, заголовки и история ответов.
Отладка обработчика по шагам
Код HTTP-сервиса выполняется на сервере, поэтому точки останова в нём ловятся только при отладке по протоколу HTTP:
- Переключите Конфигуратор на отладку по протоколу HTTP: параметр задают в окне
Сервис → Параметры. Сервер отладкиdbgsпо умолчанию слушает порт 1550. - В
default.vrdдобавьте строку<debug enable="true" protocol="http" url="http://localhost:1550"/>и перезапустите веб-сервер. - В Конфигураторе откройте
Отладка → Подключениеи включите автоматическое подключение для HTTP-сервисов. - Поставьте точку останова в обработчике и отправьте запрос из Postman.
На рабочем сервере отладку после проверки выключите. Пока строка debug активна, каждый запрос тормозит, а при остановке на точке клиент висит до таймаута.
Если отладчик подключить нельзя, пишите в журнал регистрации через ЗаписьЖурналаРегистрации() с отдельным событием, например API.Ошибка. Потом журнал легко отфильтровать по этому событию.
Скорость и нагрузка: сеансы, лицензии, тяжёлые запросы
Каждый запрос к HTTP-сервису работает в сеансе 1С. Открыть сеанс — дорого: платформа инициализирует параметры сеанса и выполняет код при начале работы. Поэтому главный рычаг скорости — свойство Повторное использование сеансов:
| Значение | Как работает | Когда ставить |
|---|---|---|
| Не использовать | Новый сеанс на каждый запрос | Редкие обращения, отладка |
| Автоматически использовать | Платформа держит пул сеансов и раздаёт их запросам | Большинство API с частыми вызовами |
| Использовать | Клиент сам держит сеанс через cookie | Клиент умеет хранить cookie и делает серию запросов |
Параметры пула в default.vrd: poolSize — сколько сеансов держать, poolTimeout — сколько секунд ждать свободный сеанс. sessionMaxAge задаёт время жизни сеанса без запросов.
Сеансы HTTP-сервисов расходуют клиентские лицензии. Пул в 10 сеансов при пиковой нагрузке займёт до 10 лицензий. Закладывайте это в расчёт, иначе пользователи утром не смогут войти в базу.
Что ещё ускоряет сервис:
- ⚡ отдавайте данные порциями: параметры
limitиoffsetв адресе вместо выгрузки всего справочника; - ⚡ в запросах выбирайте только нужные поля, без
ВЫБРАТЬ *; - ⚡ тяжёлую обработку входящих вебхуков переносите в фоновое задание: сервис сохраняет данные в регистр и сразу отвечает
202; - ⚡ на клиент-серверной базе следите за долгими запросами в технологическом журнале.
Платёжные системы и маркетплейсы часто повторяют вебхук, если не получили ответ за несколько секунд. Быстрый ответ 200 или 202 и разбор в фоне спасают от задвоения документов.
Реальные сценарии: сайт, бот, вебхуки
Несколько задач, которые закрывают HTTP-сервисом чаще всего.
Остатки и цены для интернет-магазина. GET /stock?updated_since=… отдаёт только изменившиеся позиции. Сайт опрашивает его раз в 5–15 минут. Полную выгрузку делают ночью.
Приём заказов с сайта. POST /orders принимает JSON, проверяет контрагента по ИНН или телефону и создаёт заказ покупателя. В ответ — номер документа и код 201. Повторная отправка того же заказа не должна создавать дубль: храните внешний номер заказа и проверяйте его перед записью.
Телеграм-бот для менеджеров. Бот на Python обращается к GET /debts/{inn} и показывает задолженность клиента. 1С ничего не знает о Телеграме, она отвечает только на HTTP-запрос.
Вебхуки банка и платёжного сервиса. Сервис принимает уведомление об оплате, сохраняет его и ставит в очередь. Фоновое задание раз в минуту разносит оплаты по заказам.
Мобильное приложение склада. Сборщик сканирует штрихкод, приложение запрашивает GET /goods/{barcode} и получает товар, ячейку и количество к сбору.
Частые вопросы
Можно ли запустить HTTP-сервис на файловой базе?
File="путь". Для серьёзной нагрузки лучше клиент-серверный вариант.Как вернуть файл, а не JSON?
УстановитьТелоИзДвоичныхДанных() и укажите заголовки Content-Type и Content-Disposition с именем файла.Почему изменения в коде обработчика не видны клиенту?
Как сделать версионирование API?
api_v1 и api_v2 или добавьте версию в шаблон: /v1/orders. Старую версию держите, пока все клиенты не перейдут.