HTTP-сервисы в расширении 1С: публикация, права, обновление

Дата: 10.10.2026 09:29:47
HTTP-сервис
Расширение конфигурации
REST API
Интеграция
Веб-сервер
Безопасный режим
Комментарий:
0
Платформа:
8.3
Конфигурация:
Любая
Формы:
Любые

HTTP-сервисы в расширении 1С — штатный способ сделать REST API к типовой конфигурации, не снимая её с поддержки: сервис, его модуль и роль хранятся в расширении, а типовая обновляется как обычно. Устройство самого сервиса — шаблоны URL, методы, JSON — описано в статье «HTTP-сервис 1С: создание с нуля». Здесь только то, что в расширении работает иначе.

Задача возникает в любой интеграции с УТ 11, КА 2 или БП 3.0 на поддержке. Обработчик редко бывает проблемой — ломаются публикация, подключение расширения после обновления и безопасный режим.

Как добавить HTTP-сервис в расширение 1С

  1. В конфигураторе: Конфигурация → Расширения конфигурации → Добавить. Имя — Интеграция, префикс — инт_, назначение — «Дополнение» или «Адаптация» («Исправление» — для патчей). Роль инт_ОсновнаяРоль платформа создаст сама и сделает основной ролью расширения.
  2. В конфигурации расширения добавьте в ветку Общие → HTTP-сервисы сервис инт_API с корневым URL intapi. Шаблоны и методы — как в основной конфигурации.
  3. Добавьте роль инт_ИспользованиеAPI — о ней ниже.
  4. В окне расширения выполните Конфигурация → Обновить конфигурацию базы данных (F7). Расширение подключается при старте сеанса, поэтому сервис увидят новые сеансы.

HTTP-сервисы в расширениях появились в платформе 8.3.7: режим совместимости расширения должен быть не ниже 8.3.7, а поднять его выше режима типовой нельзя. Для конфигураций в режиме 8.3.6 и ниже путь закрыт.

Префикс и корневой URL

Префикс в именах сервиса и роли проверьте сами: справка обещает автоподстановку только для новых отчётов, обработок, подсистем и обработчиков событий форм. При подключении платформа ищет конфликты имён с типовой и ранее применёнными расширениями. Если в новом релизе 1С добавит объект с вашим именем, расширение не подключится целиком — со всеми адресами API.

Корневой URL сверьте со списком HTTP-сервисов типовой: в УТ 11.4 заняты dt и edi, в КА 2.5 ещё exchange, billing и loyaltyservice. Короткий api легко совпадёт с чужим адресом.

Публикация HTTP-сервиса расширения: default.vrd

Частая жалоба: типовые сервисы отвечают, а сервис из расширения — 404. По схеме default.vrd платформы 8.3.27 у элемента httpServices атрибут publishByDefault (сервисы конфигурации) по умолчанию true, а publishExtensionsByDefault (сервисы расширений) — false.

В конфигураторе: Администрирование → Публикация на веб-сервере, вкладка «HTTP сервисы», флажок «Публиковать HTTP сервисы расширений по умолчанию», «Опубликовать». Или в файле:

<?xml version="1.0" encoding="UTF-8"?>
<point xmlns="http://v8.1c.ru/8.2/virtual-resource-system"
		xmlns:xs="http://www.w3.org/2001/XMLSchema"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		base="/trade"
		ib="Srvr=&quot;srv01&quot;;Ref=&quot;trade&quot;;">
	<!-- publishByDefault - сервисы конфигурации, publishExtensionsByDefault - сервисы расширений -->
	<httpServices publishByDefault="true"
			publishExtensionsByDefault="true">
		<!-- сервис расширения: имя с префиксом, rootUrl - как в свойствах сервиса -->
		<service name="инт_API"
				rootUrl="intapi"
				enable="true"
				reuseSessions="autouse"
				sessionMaxAge="20"
				poolSize="10"
				poolTimeout="5"/>
	</httpServices>
</point>

Элемент service задаёт повторное использование сеансов: по материалам 1С, у сервиса в расширении эти свойства в конфигураторе не редактируются, а default.vrd приоритетнее свойств конфигурации. После правки перезапустите Apache или пул IIS; публикация с нуля — в статье «Публикация 1С на веб-сервере».

Для проверки добавьте служебный метод: он покажет, какое расширение ответило и в каком режиме работает код. Шаблон /v1/diag, метод GET:

// Модуль HTTP-сервиса инт_API (расширение «Интеграция», префикс инт_).
// Шаблон /v1/diag, метод GET, обработчик ДиагностикаGET.
// Показывает, какое расширение обслуживает адрес и в каком режиме работает код.
Функция ДиагностикаGET(Запрос)

	Если Не РольДоступна("инт_ИспользованиеAPI") Тогда
		Возврат ОтветВФорматеJSON(403, Новый Структура("error", "Нет роли инт_ИспользованиеAPI"));
	КонецЕсли;

	Сервис = Метаданные.HTTPСервисы.инт_API;
	Данные = Новый Структура;
	Данные.Вставить("service", Сервис.Имя);
	Данные.Вставить("rootUrl", Сервис.КорневойURL);
	Данные.Вставить("baseUrl", Запрос.БазовыйURL);
	Данные.Вставить("user", ИмяПользователя());
	Данные.Вставить("configuration", Метаданные.Имя + " " + Метаданные.Версия);

	// Режим в момент вызова: Ложь, Истина или имя профиля безопасности
	Данные.Вставить("safeModeNow", БезопасныйРежим());
	Данные.Вставить("privilegedModeAvailable", ПривилегированныйРежимДоступен());

	Попытка
		Расширение = Сервис.РасширениеКонфигурации(); // Неопределено - сервис основной конфигурации
		Если Расширение <> Неопределено Тогда
			Данные.Вставить("extension", Расширение.Имя + " " + Расширение.Версия);
			Данные.Вставить("safeModeSetting", Расширение.БезопасныйРежим);
		КонецЕсли;
		// Истина - расширения обновили после старта этого сеанса (платформа 8.3.22+)
		Данные.Вставить("extensionsChanged", РасширенияКонфигурации.РасширенияКонфигурацииИзменены());
		Проблемы = Новый Массив;
		Для Каждого Проблема Из РасширенияКонфигурации.ПолучитьИнформациюОПроблемахПримененияВСеансе() Цикл
			Проблемы.Добавить(СтрШаблон("%1 (%2): %3", Проблема.Расширение.Имя, Проблема.Важность, Проблема.Описание));
		КонецЦикла;
		Данные.Вставить("applyIssues", Проблемы);
	Исключение
		Данные.Вставить("diagError", КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
	КонецПопытки;

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

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

// В безопасном режиме включение привилегированного режима игнорируется,
// и функция вернёт Ложь. При выходе из функции режим выключится сам.
Функция ПривилегированныйРежимДоступен()

	УстановитьПривилегированныйРежим(Истина);
	Возврат ПривилегированныйРежим();

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

// Ответ с телом JSON в UTF-8 без BOM
Функция ОтветВФорматеJSON(КодСостояния, Данные)

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

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

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

Запрос https://srv01/trade/hs/intapi/v1/diag под техническим пользователем вернёт JSON с именем и версией расширения. Без роли — 403: версию конфигурации посторонним видеть незачем.

Безопасный режим: что он запрещает сервису

По умолчанию расширение работает в безопасном режиме — колонка «Безопасный режим, имя профиля безопасности» в окне Конфигурация → Расширения конфигурации. Для обработчика это значит:

Что делает обработчикВ безопасном режимеКак быть
Читает и пишет данныеТолько с правами пользователя, с RLSВыдать права в роли расширения
УстановитьПривилегированныйРежим(Истина)Вызов игнорируетсяПрава или выключить режим
Вызывает внешний API через HTTPСоединениеИнтернет запрещёнПрофиль безопасности или выключить режим
Пишет временный файл: PDF, XLSX, ZIPФайловая система запрещенаСобирать файл в ПотокВПамяти
COM, внешняя компонента, запуск программыЗапрещеноТолько без безопасного режима

Выключают режим в той же колонке конфигуратора или в 1С:Предприятии: в УТ 11.4 — НСИ и администрирование → Печатные формы, отчеты и обработки → Расширения, флажок «Безопасный режим»; нужно право «Администрирование». При профилях безопасности в кластере небезопасное расширение должен разрешать основной профиль. Промежуточный вариант — выбрать в колонке профиль, где разрешено только нужное, например один внешний адрес.

Без безопасного режима код расширения может всё, что код типовой. Если хватает прав пользователя и не нужны файлы и интернет, режим лучше оставить. Сработает ли привилегированный режим, покажет поле privilegedModeAvailable в /v1/diag.

Права: своя роль в расширении

Отдельного права на HTTP-сервис в ролях нет, в отличие от операций web-сервисов. В обработчик попадает аутентифицированный пользователь, дальше решают права на данные — без привилегированного режима технический пользователь должен иметь их сам.

  • Своя роль инт_ИспользованиеAPI: заимствуйте объекты, которые читает сервис (контекстное меню → «Добавить в расширение»), и отметьте «Чтение». По этой роли обработчик отличает API от сотрудников.
  • Основная роль инт_ОсновнаяРоль даёт доступ только к собственным объектам расширения, права на заимствованные в ней не задать. Флажок «Использовать основные роли для всех пользователей» в окне расширений выдаёт её всем.
  • На БСП роль включают в профиль: НСИ и администрирование → Настройки пользователей и прав → Профили групп доступа, вкладка «Разрешенные действия (роли)». Роль, выданную в обход профилей, БСП снимет при пересчёте ролей по группам доступа.
  • Без БСП роль расширения назначают из сеанса, где расширение подключено:
// Внешняя обработка, модуль объекта. Запускать администратором в 1С:Предприятии,
// в сеансе, где расширение подключено. Только для конфигураций без БСП:
// в БСП пользователей ведут в справочнике «Пользователи», а роли выдают профилями.
Процедура НастроитьПользователяAPI(ЛогинAPI, ПарольAPI = "") Экспорт

	РольAPI = Метаданные.Роли.Найти("инт_ИспользованиеAPI");
	Если РольAPI = Неопределено Тогда
		ВызватьИсключение "Роль инт_ИспользованиеAPI не найдена: расширение не подключено в этом сеансе";
	КонецЕсли;

	ПользовательAPI = ПользователиИнформационнойБазы.НайтиПоИмени(ЛогинAPI);
	Если ПользовательAPI = Неопределено Тогда
		Если ПустаяСтрока(ПарольAPI) Тогда
			ВызватьИсключение "Новому пользователю API нужен пароль";
		КонецЕсли;
		ПользовательAPI = ПользователиИнформационнойБазы.СоздатьПользователя();
		ПользовательAPI.Имя = ЛогинAPI;
		ПользовательAPI.ПолноеИмя = "Интеграция: " + ЛогинAPI;
	КонецЕсли;

	ПользовательAPI.АутентификацияСтандартная = Истина;
	ПользовательAPI.ПоказыватьВСпискеВыбора = Ложь;
	Если Не ПустаяСтрока(ПарольAPI) Тогда
		ПользовательAPI.Пароль = ПарольAPI; // пароль передают параметром, в коде его не храним
	КонецЕсли;
	Если Не ПользовательAPI.Роли.Содержит(РольAPI) Тогда
		ПользовательAPI.Роли.Добавить(РольAPI);
	КонецЕсли;
	ПользовательAPI.Записать();

КонецПроцедуры

Права своей роли складываются с правами типовых: «Чтение» без ограничения на уровне записей откроет все записи, даже если типовые роли ограничивают пользователя. В профили сотрудников такую роль не включайте. Подробнее — про роли и RLS.

Обработчик ниже проверяет права заранее и называет недостающие, а заодно ловит объекты, переименованные в новом релизе типовой. Шаблон /v1/stock, метод GET:

// Модуль HTTP-сервиса инт_API. Шаблон /v1/stock, метод GET, обработчик ОстаткиGET.
// Справочник и регистр - из УТ 11.4 и КА 2.5.
Функция ОстаткиGET(Запрос)

	Отказ = ПроверкаДоступа("Справочник.Номенклатура, РегистрНакопления.ТоварыНаСкладах");
	Если Отказ <> Неопределено Тогда
		Возврат Отказ;
	КонецЕсли;

	Попытка
		Остатки = ОстаткиТоваров();
	Исключение
		Возврат ОтветСИнцидентом(Запрос, ИнформацияОбОшибке());
	КонецПопытки;

	Товары = Новый Массив;
	Для Каждого Позиция Из Остатки Цикл
		Товары.Добавить(Новый Структура("code, name, qty",
			СокрЛП(Позиция.Код), Позиция.Наименование, Позиция.Количество));
	КонецЦикла;

	Возврат ОтветВФорматеJSON(200, Новый Структура("items", Товары));

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

// Неопределено - можно работать, иначе готовый ответ 403 или 500.
// Без привилегированного режима нужны права самого пользователя: проверяем их заранее
// и называем недостающие, а не ловим «Нарушение прав доступа!» посреди запроса.
Функция ПроверкаДоступа(ИменаОбъектов)

	Если Не РольДоступна("инт_ИспользованиеAPI") Тогда
		Возврат ОтветВФорматеJSON(403, Новый Структура("error", "Нет роли инт_ИспользованиеAPI"));
	КонецЕсли;

	НетОбъектов = Новый Массив;
	НетПрав = Новый Массив;
	Для Каждого ПолноеИмя Из СтрРазделить(ИменаОбъектов, ",", Ложь) Цикл
		ОбъектМД = Метаданные.НайтиПоПолномуИмени(СокрЛП(ПолноеИмя));
		Если ОбъектМД = Неопределено Тогда
			НетОбъектов.Добавить(СокрЛП(ПолноеИмя)); // переименован или удалён в новом релизе типовой
		ИначеЕсли Не ПравоДоступа("Чтение", ОбъектМД) Тогда
			НетПрав.Добавить(ОбъектМД.ПолноеИмя());
		КонецЕсли;
	КонецЦикла;

	Если НетОбъектов.Количество() > 0 Тогда
		ТекстОшибки = "В конфигурации нет объектов: " + СтрСоединить(НетОбъектов, ", ");
		Возврат ОтветВФорматеJSON(500, Новый Структура("error", ТекстОшибки));
	ИначеЕсли НетПрав.Количество() > 0 Тогда
		ТекстОшибки = "Нет права Чтение: " + СтрСоединить(НетПрав, ", ");
		Возврат ОтветВФорматеJSON(403, Новый Структура("error", ТекстОшибки));
	КонецЕсли;

	Возврат Неопределено;

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

// Ответ 500 с номером инцидента: клиент получает номер, подробности - в журнале регистрации
Функция ОтветСИнцидентом(Запрос, Информация)

	Инцидент = Строка(Новый УникальныйИдентификатор);
	Комментарий = СтрШаблон("%1 %2%3%4%5", Запрос.HTTPМетод, Запрос.БазовыйURL, Запрос.ОтносительныйURL,
		Символы.ПС, ПодробноеПредставлениеОшибки(Информация));
	ЗаписьЖурналаРегистрации("инт_API.Ошибка", УровеньЖурналаРегистрации.Ошибка,
		Метаданные.HTTPСервисы.инт_API, Инцидент, Комментарий);

	Тело = Новый Структура;
	Тело.Вставить("error", КраткоеПредставлениеОшибки(Информация));
	Тело.Вставить("incident", Инцидент);
	Возврат ОтветВФорматеJSON(500, Тело);

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

// Остатки по всем складам. РАЗРЕШЕННЫЕ: при ограничениях на уровне записей
// запрос вернёт доступные строки, а не ошибку.
Функция ОстаткиТоваров()

	ЗапросОстатков = Новый Запрос;
	ЗапросОстатков.Текст =
	"ВЫБРАТЬ РАЗРЕШЕННЫЕ
	|	Остатки.Номенклатура.Код КАК Код,
	|	Остатки.Номенклатура.Наименование КАК Наименование,
	|	СУММА(Остатки.ВНаличииОстаток) КАК Количество
	|ИЗ
	|	РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
	|СГРУППИРОВАТЬ ПО
	|	Остатки.Номенклатура.Код,
	|	Остатки.Номенклатура.Наименование
	|ИМЕЮЩИЕ
	|	СУММА(Остатки.ВНаличииОстаток) > 0
	|УПОРЯДОЧИТЬ ПО
	|	Наименование";

	Возврат ЗапросОстатков.Выполнить().Выгрузить();

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

Файл без временного файла

Схема «записать во временный файл и отдать» в безопасном режиме не работает. Табличный документ пишется прямо в поток. Шаблон /v1/stock.xlsx:

// Модуль HTTP-сервиса инт_API. Шаблон /v1/stock.xlsx, метод GET, обработчик ОстаткиXLSXGET.
// Во временный файл в безопасном режиме не записать, поэтому книга собирается в памяти.
Функция ОстаткиXLSXGET(Запрос)

	Отказ = ПроверкаДоступа("Справочник.Номенклатура, РегистрНакопления.ТоварыНаСкладах");
	Если Отказ <> Неопределено Тогда
		Возврат Отказ;
	КонецЕсли;

	Попытка
		ТабДок = Новый ТабличныйДокумент;
		ВывестиСтрокуОстатков(ТабДок, 1, "Код", "Номенклатура", "В наличии");
		НомерСтроки = 1;
		Для Каждого Позиция Из ОстаткиТоваров() Цикл
			НомерСтроки = НомерСтроки + 1;
			ВывестиСтрокуОстатков(ТабДок, НомерСтроки, СокрЛП(Позиция.Код), Позиция.Наименование, Позиция.Количество);
		КонецЦикла;

		Поток = Новый ПотокВПамяти;
		ТабДок.Записать(Поток, ТипФайлаТабличногоДокумента.XLSX);
		Книга = Поток.ЗакрытьИПолучитьДвоичныеДанные();
	Исключение
		Возврат ОтветСИнцидентом(Запрос, ИнформацияОбОшибке());
	КонецПопытки;

	Ответ = Новый HTTPСервисОтвет(200);
	Ответ.Заголовки.Вставить("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
	Ответ.Заголовки.Вставить("Content-Disposition", "attachment; filename=""stock.xlsx""");
	Ответ.УстановитьТелоИзДвоичныхДанных(Книга);
	Возврат Ответ;

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

// Код и наименование - текстом, количество - числом: в Excel по колонке работают суммы
Процедура ВывестиСтрокуОстатков(ТабДок, НомерСтроки, Код, Наименование, Количество)

	ТабДок.Область(НомерСтроки, 1).Текст = Код;
	ТабДок.Область(НомерСтроки, 2).Текст = Наименование;

	Ячейка = ТабДок.Область(НомерСтроки, 3);
	Если ТипЗнч(Количество) = Тип("Число") Тогда
		Ячейка.СодержитЗначение = Истина;
		Ячейка.ТипЗначения = Новый ОписаниеТипов("Число");
		Ячейка.Значение = Количество;
	Иначе
		Ячейка.Текст = Количество; // строка заголовка
	КонецЕсли;

КонецПроцедуры

Обновление типовой и расширения

  1. Обновите типовую на копии и в окне «Расширения конфигурации» выполните Конфигурация → Проверка возможности применения: она сверит заимствованные объекты и найдёт конфликты имён.
  2. В конфигурации расширения запустите Конфигурация → Проверка модулей. Если 1С переименовала вызываемый метод, расширение подключится, а обработчик упадёт с кодом 500.
  3. Выполните функцию из листинга ниже и вызовите методы сервиса на копии. Порядок на рабочей базе — в статье «Расширение конфигурации 1С».
  4. После загрузки новой версии расширения перезапустите веб-сервер или пул IIS либо завершите сеансы HTTP-сервиса в консоли кластера.

Последний пункт — особенность HTTP-сервисов. При reuseSessions="autouse" или "use" сеанс завершается, только простояв sessionMaxAge секунд. Если сайт опрашивает API каждые 10 секунд, сеанс живёт сутками со своей стартовой версией расширения. В нём РасширенияКонфигурации.РасширенияКонфигурацииИзменены() (8.3.22+) вернёт Истина — поле extensionsChanged в /v1/diag.

// Внешняя обработка, модуль объекта. Запускать администратором на копии базы после
// обновления типовой, в новом сеансе: какие HTTP-сервисы дают расширения,
// не занят ли их корневой URL другим сервисом и что мешает подключить расширение.
Функция ПроверитьHTTPСервисыРасширений() Экспорт

	Результат = Новый ТаблицаЗначений;
	Результат.Колонки.Добавить("Расширение", Новый ОписаниеТипов("Строка"));
	Результат.Колонки.Добавить("Сервис", Новый ОписаниеТипов("Строка"));
	Результат.Колонки.Добавить("КорневойURL", Новый ОписаниеТипов("Строка"));
	Результат.Колонки.Добавить("Замечания", Новый ОписаниеТипов("Строка"));

	// Все сервисы сеанса: основной конфигурации и подключённых расширений
	ВладельцыURL = Новый Соответствие;
	Для Каждого Сервис Из Метаданные.HTTPСервисы Цикл
		Ключ = НРег(Сервис.КорневойURL);
		Если ВладельцыURL.Получить(Ключ) = Неопределено Тогда
			ВладельцыURL.Вставить(Ключ, Новый Массив);
		КонецЕсли;
		ВладельцыURL.Получить(Ключ).Добавить(Сервис.Имя);
	КонецЦикла;

	Для Каждого Расширение Из РасширенияКонфигурации.Получить() Цикл

		Общие = Новый Массив;
		НеПодключится = Не Расширение.Активно;
		Если НеПодключится Тогда
			Общие.Добавить("расширение выключено");
		КонецЕсли;
		Если Расширение.БезопасныйРежим <> Ложь Тогда
			Общие.Добавить("безопасный режим");
		КонецЕсли;
		Для Каждого Проблема Из Расширение.ПроверитьВозможностьПрименения() Цикл
			Общие.Добавить(СтрШаблон("%1: %2", Проблема.Важность, Проблема.Описание));
			Если Проблема.Важность = ВажностьПроблемыПримененияРасширенияКонфигурации.Критичная Тогда
				НеПодключится = Истина;
			КонецЕсли;
		КонецЦикла;

		Если НеПодключится Тогда
			// Неподключённого расширения нет в Метаданные: его адреса ответят 404
			ДобавитьСтрокуПроверки(Результат, Расширение, "все HTTP-сервисы расширения", "", Общие);
			Продолжить;
		КонецЕсли;

		Для Каждого Сервис Из Метаданные.HTTPСервисы Цикл
			Владелец = Сервис.РасширениеКонфигурации();
			Если Владелец = Неопределено Или Владелец.Имя <> Расширение.Имя Тогда
				Продолжить;
			КонецЕсли;
			Замечания = Новый Массив;
			Для Каждого Текст Из Общие Цикл
				Замечания.Добавить(Текст);
			КонецЦикла;
			Владельцы = ВладельцыURL.Получить(НРег(Сервис.КорневойURL));
			Если Владельцы.Количество() > 1 Тогда
				Замечания.Добавить("один корневой URL у сервисов " + СтрСоединить(Владельцы, ", "));
			КонецЕсли;
			ДобавитьСтрокуПроверки(Результат, Расширение, Сервис.Имя, Сервис.КорневойURL, Замечания);
		КонецЦикла;

	КонецЦикла;

	Возврат Результат;

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

Процедура ДобавитьСтрокуПроверки(Результат, Расширение, ИмяСервиса, КорневойURL, Замечания)

	НоваяСтрока = Результат.Добавить();
	НоваяСтрока.Расширение = СтрШаблон("%1 %2", Расширение.Имя, Расширение.Версия);
	НоваяСтрока.Сервис = ИмяСервиса;
	НоваяСтрока.КорневойURL = КорневойURL;
	НоваяСтрока.Замечания = СтрСоединить(Замечания, "; ");

КонецПроцедуры

Отладка сервиса в расширении

Отладку на сервере включают как обычно — см. «Отладка на сервере 1С». Отличия:

  • Точку останова ставят в модуле сервиса в окне конфигурации расширения, предварительно выполнив F7: выполняется то, что применено в базе.
  • В Отладка → Подключение → Автоматическое подключение отметьте «HTTP-сервисы»: сеанс сервиса возникает по запросу, вручную его заранее не подключить.
  • На время отладки поставьте сервису в default.vrd reuseSessions="dontuse": каждый запрос получит новый сеанс со свежей версией расширения.

На рабочей базе вместо отладчика — журнал регистрации: обработчик остатков пишет событие инт_API.Ошибка и отдаёт клиенту номер инцидента. Если запрос до 1С не доходит, смотрите логи веб-сервера и технологический журнал.

Разбор ключевых строк

  • Сервис.РасширениеКонфигурации() — расширение, которое добавило сервис, или Неопределено для сервиса основной конфигурации.
  • ПривилегированныйРежимДоступен() — приём из БСП: включить режим и сразу спросить. В безопасном режиме функция вернёт Ложь.
  • ПолучитьИнформациюОПроблемахПримененияВСеансе() — с какими проблемами расширение подключилось, например метод с &ИзменениеИКонтроль не расширен.
  • ПравоДоступа("Чтение", ОбъектМД) без третьего параметра проверяет текущего пользователя и не требует административных прав; в привилегированном режиме всегда возвращает Истина.
  • ВажностьПроблемыПримененияРасширенияКонфигурации.Критичная в проверке после обновления значит, что расширение не подключится.

Типичные ошибки

Симптом или текст ошибкиПричинаЧто сделать
404 на /hs/intapi/…, а типовые сервисы отвечаютНет publishExtensionsByDefault="true" или элемента serviceФлажок публикации или правка default.vrd, перезапуск веб-сервера
«Использование HTTP-сервисов в расширениях недопустимо в режиме совместимости 8.3.6 и ниже»Режим совместимости расширения ниже 8.3.7Поднять его, но не выше режима типовой
«Режим совместимости расширения конфигурации больше режима совместимости основной конфигурации»Режим расширения выше режима типовойПонизить режим расширения
500 и «Нарушение прав доступа!»Привилегированный режим проигнорирован, прав у пользователя нетПрава в роли расширения, см. «Нарушение прав доступа в 1С»
500 и «Установлен безопасный режим. Выполнение операции запрещено»Файл, HTTPСоединение или COM в безопасном режимеПоток в памяти, профиль безопасности или выключить режим
500 и «Метод объекта не обнаружен (…)», «Поле объекта не обнаружено (…)»В новом релизе типовой метод или реквизит переименованПроверка модулей, вызов методов на копии
После загрузки новой версии сервис работает по-старомуСеанс из пула стартовал до обновленияПерезапуск веб-сервера, поле extensionsChanged
У технического пользователя пропала рольНа БСП роль выдали в обход профиляВключить роль в профиль групп доступа

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

Нужно ли заимствовать типовые объекты, чтобы читать их из сервиса?

Для кода — нет: запросы, менеджеры объектов и экспортные методы общих модулей типовой вызываются напрямую. Заимствование нужно для прав в роли расширения, перехвата методов и типов реквизитов расширения.

Как оставить в публикации только свой API?

Поставьте publishByDefault="false" и publishExtensionsByDefault="true", лишние сервисы других расширений выключите элементами service с enable="false". Сначала убедитесь, что типовые сервисы (в УТ 11.4 — dt и edi) никто не вызывает.

Что будет с API, если расширение не подключится после обновления?

Сервис пропадёт из метаданных сеанса, и его адреса начнут отвечать 404. Данные типовой не пострадают, но сайт останется без обмена. Причину покажет листинг проверки, а на рабочей базе стоит периодически опрашивать /v1/diag.

Можно ли держать HTTP-сервисы в нескольких расширениях?

Да: имена расширений уникальны, у сервисов — разные имена и корневые URL. Совпадение адресов покажет листинг проверки после обновления.

Когда проще заказать

Если API нужен под конкретный сайт или маркетплейс и должен переживать обновления типовой, поручите расширение, публикацию и проверку на копии исполнителю: услуги по доработке 1С, для сайтов — обмен 1С с сайтом. Опишите конфигурацию и методы в форме задания — оценка бесплатная, ответ в течение рабочего дня.

По теме

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.


1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.