Свой REST API для базы 1С:Предприятие 8.3 — от публикации до первого JSON-ответа

· 9 мин

Содержание

Чтобы подключить API к 1С 8.3, в конфигурации создают объект HTTP-сервис (Общие → HTTP-сервисы), пишут обработчики методов на встроенном языке, а базу публикуют на веб-сервере через Администрирование → Публикация на веб-сервере в конфигураторе. После этого сервис отвечает по адресу вида http://сервер/имя_публикации/hs/корневой_URL/шаблон.

Частое заблуждение — что у 1С есть «готовый API», который нужно просто включить. Готовый есть только один: стандартный интерфейс OData. Он отдаёт справочники и документы как есть, но бизнес-логики в нём нет. Если внешней системе нужно «создай заказ и верни номер» или «отдай остатки по складу одним запросом», без своего HTTP-сервиса не обойтись. Интеграцию 1С с внешним API в обратную сторону (1С сама ходит в чужой сервис) делают другими объектами — о них ниже, в отдельном разделе.

Что подготовить до начала: веб-сервер и публикация базы

HTTP-сервис живёт внутри конфигурации, но наружу его выставляет веб-сервер. Сама платформа порт для REST-запросов не открывает.

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

  • 🖥️ Веб-сервер — Apache 2.4 или IIS. Для Linux — Apache.
  • 🧩 Модули расширения веб-сервера — компонент дистрибутива платформы. При установке 1С отметьте пункт «Модули расширения веб-сервера».
  • 🔢 Совпадение разрядности. 64-битный Apache работает только с 64-битной платформой, 32-битный — с 32-битной.
  • 🔐 Права конфигуратора у того, кто публикует, и права администратора Windows (публикация пишет в каталог веб-сервера и его настройки).

Публикация через конфигуратор

  1. Запустите конфигуратор от имени администратора Windows.
  2. Откройте Администрирование → Публикация на веб-сервере.
  3. Задайте имя публикации латиницей, например trade. Оно станет частью адреса.
  4. Выберите веб-сервер (Apache 2.4 или IIS) и каталог публикации.
  5. На вкладке HTTP-сервисов оставьте флажок публикации HTTP-сервисов по умолчанию — иначе адреса /hs/ будут отвечать 404.
  6. Нажмите Опубликовать и согласитесь на перезапуск веб-сервера.

Перезапуск Apache или IIS обрывает все текущие веб-подключения: тонкий клиент через браузер, другие опубликованные базы. На рабочем сервере публикуйте вне рабочих часов.

В каталоге публикации появится файл default.vrd. Это главный конфиг: строка подключения к базе, список опубликованных сервисов, параметры отладки. Для серверной базы строка выглядит как Srvr="srv1c";Ref="trade";, для файловой — как File="D:\Bases\Trade";.

Публикация без конфигуратора

На Linux и на серверах без графики используют утилиту webinst из каталога bin платформы. Пример для Apache:

webinst -publish -apache24 -wsdir trade -dir "C:\inetpub\trade" -connstr "Srvr=srv1c;Ref=trade;" -confpath "C:\Apache24\conf\httpd.conf"

Точный набор ключей для вашей версии смотрите в выводе webinst -help: он менялся между релизами платформы.

Создание HTTP-сервиса в конфигураторе

Структура объекта трёхуровневая: сервис → шаблоны URL → методы. Каждый уровень отвечает за свою часть адреса.

УровеньЧто задаётПример
HTTP-сервисКорневой URLapi
Шаблон URLПуть и параметры/goods/{id}
МетодHTTP-метод и обработчикGET → GoodsGet

Порядок действий:

  1. Если конфигурация типовая, сначала создайте расширение (Конфигурация → Расширения конфигурации → Добавить). Так сервис переживёт обновления типовой и не снимет её с поддержки.
  2. В дереве откройте Общие → HTTP-сервисы, добавьте новый.
  3. Заполните Корневой URL латиницей без слэшей: api.
  4. На вкладке шаблонов добавьте шаблон /goods/{id}. Фигурные скобки — параметр, его значение придёт в обработчик.
  5. Внутри шаблона добавьте метод, выберите HTTP-метод GET, нажмите на лупу у поля «Обработчик» — платформа создаст процедуру в модуле сервиса.
  6. Для записи данных добавьте второй шаблон /orders с методом POST.
  7. Сохраните и обновите конфигурацию базы (F7).

Итоговый адрес: http://server/trade/hs/api/goods/42.

У сервиса есть свойство повторного использования сеансов («Использовать», «Не использовать», «Автоматически») и время жизни сеанса. При частых коротких запросах повторное использование заметно сокращает время ответа: платформе не приходится каждый раз заново открывать сеанс.

Пустая база с новым сервисом и опубликованным default.vrd уже отвечает — пусть и ошибкой 500, пока обработчик не написан. Это удобная точка проверки: если вместо 500 приходит 404, проблема в публикации, а не в коде.

Обработка запроса и ответ в формате JSON

Обработчик получает объект HTTPСервисЗапрос и обязан вернуть HTTPСервисОтвет. Из запроса берут:

  • 🔗 Запрос.ПараметрыURL["id"] — параметр из шаблона;
  • ❓ Запрос.ПараметрыЗапроса["limit"] — параметр после ? в адресе;
  • 📦 Запрос.ПолучитьТелоКакСтроку() — тело POST-запроса;
  • 🏷️ Запрос.Заголовки — заголовки.

GET: отдаём товар по коду

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

	Код = Запрос.ПараметрыURL["id"];
	Ссылка = Справочники.Номенклатура.НайтиПоКоду(Код);

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

	Данные = Новый Структура;
	Данные.Вставить("code", Код);
	Данные.Вставить("name", Ссылка.Наименование);
	Данные.Вставить("uuid", Строка(Ссылка.УникальныйИдентификатор()));

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

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

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

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

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

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

Две детали, которые экономят день отладки:

  • ЗаписатьJSON не умеет сериализовать ссылки на объекты базы. В структуру кладите строки, числа, даты, булевы значения — или уникальный идентификатор строкой, как в примере.
  • Без ИспользованиеByteOrderMark.НеИспользовать в начало тела попадает BOM. Часть клиентов (особенно на PHP и JavaScript) после этого не может разобрать JSON.

POST: принимаем заказ

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

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

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

	// здесь создание и запись документа
	Возврат ОтветJSON(201, Новый Структура("status", "created"));

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

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

Отвечайте кодами по смыслу: 400 — сломанный запрос, 404 — нет объекта, 422 — данные не прошли проверку, 500 — ваша ошибка. Внешнему разработчику так проще понять, кто виноват.

Когда 1С сама обращается к внешнему API

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

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

Запрос = Новый HTTPЗапрос("/v1/orders");
Запрос.Заголовки.Вставить("Content-Type", "application/json");
Запрос.Заголовки.Вставить("Authorization", "Bearer " + Токен);
Запрос.УстановитьТелоИзСтроки(ТекстJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

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

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

Что запомнить:

  • ОтправитьДляОбработки — это POST, Получить — GET, Записать — PUT, Удалить — DELETE. Для остальных методов есть ВызватьHTTPМетод.
  • Шестой параметр конструктора соединения — таймаут в секундах. Без него зависший внешний сервис подвесит фоновое задание.
  • Токены внешних сервисов не храните в коде и в обычных реквизитах. В конфигурациях на БСП для этого есть безопасное хранилище данных — общий модуль ОбщегоНазначения, методы ЗаписатьДанныеВБезопасноеХранилище и ПрочитатьДанныеИзБезопасногоХранилища.

Регулярный обмен (раз в 10 минут выгружать новые заказы) вешайте на регламентное задание, а не на кнопку пользователя.

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

По умолчанию HTTP-сервис требует Basic-авторизацию пользователем информационной базы. Клиент передаёт заголовок Authorization: Basic <логин:пароль в Base64>, платформа сама проверяет пароль и открывает сеанс от имени этого пользователя.

СпособКак настроитьКогда подходит
Basic пользователем 1СНичего, работает сразуВнутренняя сеть, HTTPS обязателен
Аутентификация ОСФлажок у пользователя 1С + настройки IISДомен Windows
Анонимный доступЛогин и пароль в строке подключения default.vrdПубличные данные только для чтения
Свой токен в заголовкеАнонимный вход + проверка токена в обработчикеИнтеграция с внешними сервисами

Правила, которые закрывают большинство дыр:

  1. Отдельный пользователь под интеграцию. Не админ, не бухгалтер. Только роли, нужные сервису, и без права интерактивного входа.
  2. Только HTTPS. Basic передаёт пароль фактически открытым текстом. Сертификат ставят на уровне Apache или IIS, 1С тут ничего не настраивает.
  3. Не выставляйте публикацию в интернет напрямую. Ставьте перед ней обратный прокси (nginx) с ограничением по IP и частоте запросов.
  4. Привилегированный режим — точечно. УстановитьПривилегированныйРежим(Истина) внутри обработчика снимает все ограничения прав. Если без него никак, включайте только на конкретную операцию и выключайте сразу после.

Анонимная публикация с логином администратора в default.vrd — открытая дверь в базу. Любой, кто узнает адрес, получит доступ ко всем опубликованным сервисам с полными правами.

Отладка и тестирование интеграции

Начинайте проверку с внешнего клиента, а не с кода. Самый быстрый — curl:

curl -u integr:Pa55word "http://server/trade/hs/api/goods/42"

curl -u integr:Pa55word -X POST -H "Content-Type: application/json" -d "{\"client\":\"0001\"}" "http://server/trade/hs/api/orders"

Ключ -v покажет заголовки и код ответа. Для ручных сценариев удобнее Postman или Insomnia: там сохраняются коллекции запросов, и их можно отдать внешнему разработчику как документацию.

Пошаговая отладка обработчика

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

  1. Для серверной базы запустите сервер 1С с отладкой по протоколу HTTP (в свойствах службы ключ -debug -http). Для файловой базы отладка через веб-сервер тоже идёт по HTTP.
  2. В default.vrd включите отладку для публикации — элемент debug с атрибутом enable="true" и адресом сервера отладки. Это же можно отметить в окне публикации.
  3. В конфигураторе откройте Отладка → Подключение, затем «Автоматическое подключение» и отметьте HTTP-сервисы.
  4. Поставьте точку останова и отправьте запрос из curl.

Перезапуск службы сервера 1С для включения отладки обрывает сеансы всех пользователей. На рабочем сервере это делают в окно обслуживания. Отлаживайте на копии базы.

Логирование

На рабочей базе отладчик не включают, поэтому пишите в журнал регистрации входящий запрос и текст исключения. Схема простая: тело обработчика оборачивается в Попытка … Исключение, в ветке исключения — ЗаписьЖурналаРегистрации с ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), а клиенту уходит ответ 500 с коротким текстом без подробностей.

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

Типичные ошибки при подключении API к 1С

Коды ответов разобраны выше. Здесь — ошибки проектирования, которые проявляются не сразу, а через месяц работы.

  • 🐢 Тяжёлая работа в синхронном обработчике. Клиент ждёт 2 минуты, отваливается по таймауту, повторяет запрос — и документ создаётся дважды. Долгие операции принимайте в очередь (регистр сведений), отвечайте 202 и обрабатывайте фоновым заданием.
  • 🔁 Нет защиты от повторов. Внешние системы повторяют запросы при сбоях сети. Передавайте в запросе внешний идентификатор и проверяйте, не создан ли уже объект с ним.
  • 🔄 Обновили платформу — сервис пропал. Модули веб-сервера в httpd.conf ссылаются на каталог конкретной версии. После обновления платформы и удаления старой версии базу нужно переопубликовать.
  • 🧱 Сервис в основной конфигурации типовой. Первое же обновление вызовет конфликт при сравнении-объединении. Держите HTTP-сервисы в расширении.
  • 📜 Нет версии в URL. Корневой URL api/v1 или шаблон /v1/goods позволяет потом выпустить вторую версию, не ломая старых клиентов.
Чем HTTP-сервис отличается от веб-сервиса в 1С?
Веб-сервис работает по SOAP и описывается WSDL, HTTP-сервис — это REST с произвольным форматом тела. Для новых интеграций обычно выбирают HTTP-сервисы: с JSON проще работать на любой стороне.
Можно ли сделать HTTP-сервис в файловой базе?
Да. Файловую базу тоже публикуют на веб-сервере, и HTTP-сервисы в ней работают. Для нагрузки больше нескольких запросов в секунду лучше клиент-серверный вариант.
Расходует ли обращение к HTTP-сервису лицензию?
Каждый запрос выполняется в сеансе информационной базы, а сеансы учитываются при лицензировании. Повторное использование сеансов снижает их число. Точные условия для вашего типа лицензий уточните у партнёра, продавшего лицензии.
Как получить список всех справочников без программирования?
Включите стандартный интерфейс OData: опубликуйте базу с флажком OData и задайте состав объектов. В конфигурациях на БСП это делают обработкой настройки автоматического REST-сервиса, в коде — методом УстановитьСоставСтандартногоИнтерфейсаOData. Данные будут доступны по адресу /odata/standard.odata/.
Нужен ли отдельный сервер под API?
Не обязательно. Веб-сервер можно поставить на сервер 1С. Выносить его отдельно стоит, когда API открыт наружу или нагрузка мешает пользователям.