При разработке интеграционных механизмов на платформе 1С разработчики часто сталкиваются с ситуацией, когда один и тот же программный код выборки данных и генерации XML-документа корректно отрабатывает во внешней обработке, но при выполнении в модуле HTTP-сервиса возвращает лишь корневой тег (например, <Реализации/>) без строк с данными. Проанализируем причины такого поведения платформы, разберем типовые архитектурные ошибки и рассмотрим правильные варианты реализации передачи информации.
Когда мы тестируем код в интерактивной обработке, сеанс запускается под текущим пользователем системы (как правило, с полными административными правами). Вызов же HTTP-сервиса происходит в контексте пользователя, указанного в файле публикации (default.vrd) или переданного в заголовке базовой аутентификации.
Если у сервисной учетной записи отсутствуют права на чтение требуемых метаданных либо включен механизм ограничения прав на уровне записей (RLS), запрос к базе данных вернет пустую выборку. В результате объект ЗаписьXML создаст только открывающий и закрывающий корневые теги.
Для гарантированного обхода ограничений прав в коде метода HTTP-сервиса можно принудительно включить привилегированный режим:
Функция ВыгрузитьРеализацииGET(Запрос)
УстановитьПривилегированныйРежим(Истина);
// Формирование выборки данных и XML
Ответ = Новый HTTPСервисОтвет(200);
Возврат Ответ;
КонецФункции
Параметры, передаваемые в строке адреса (query parameters), считываются через коллекцию HTTPСервисЗапрос.ПараметрыЗапроса исключительно в виде строковых значений. Если в запросе к данным условие отбора ожидает дату или ссылку, а разработчик передает нетипизированную строку, запрос не вернет ни одной записи.
Разберем по шагам, как правильно преобразовать входящие параметры:
Запрос.ПараметрыЗапроса.Получить("ДатаНачала").XMLЗначение() или явного приведения к типу Дата.
СтрокаДаты = Запрос.ПараметрыЗапроса.Получить("ДатаС");
Если ЗначениеЗаполнено(СтрокаДаты) Тогда
ДатаС = XMLЗначение(Тип("Дата"), СтрокаДаты);
ЗапросКБД.УстановитьПараметр("ДатаС", ДатаС);
КонецЕсли;
При передаче строковых параметров в строке URL пробелы, кириллические буквы и спецсимволы могут искажаться сервером публикации, если они не были экранированы. Для предотвращения повреждения данных при передаче параметров через строку запроса необходимо использовать функции экранирования:
КодироватьСтроку().РаскодироватьСтроку().
// Пример на стороне отправителя:
ПараметрЗапроса = КодироватьСтроку("Тиара", СпособКодированияСтроки.КодировкаURL);
// Пример на стороне HTTP-сервиса (получателя):
ИмяКлиента = РаскодироватьСтроку(Запрос.ПараметрыЗапроса.Получить("Клиент"), СпособКодированияСтроки.КодировкаURL);
При генерации XML-строки в оперативной памяти с помощью метода ЗаписьXML.УстановитьСтроку() обязательно требуется завершить формирование вызовом метода Закрыть() перед извлечением результирующего текста через ПолучитьСтроку(). В противном случае внутренний буфер записи может не сбросить закрывающие теги и часть данных.
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку("UTF-8");
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("Реализации");
Выборка = ЗапросКБД.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ЗаписьXML.ЗаписатьНачалоЭлемента("СтрокаРеализации");
ЗаписьXML.ЗаписатьАтрибут("Номер", Строка(Выборка.Номер));
ЗаписьXML.ЗаписатьАтрибут("Сумма", XMLСтрока(Выборка.СуммаДокумента));
ЗаписьXML.ЗаписатьАтрибут("Контрагент", Строка(Выборка.КонтрагентНаименование));
ЗаписьXML.ЗаписатьКонецЭлемента();
КонецЦикла;
ЗаписьXML.ЗаписатьКонецЭлемента(); // Реализации
ТекстXML = ЗаписьXML.Закрыть();
Ответ = Новый HTTPСервисОтвет(200);
Ответ.Заголовки.Вставить("Content-Type", "application/xml; charset=utf-8");
Ответ.УстановитьТелоИзСтроки(ТекстXML, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Возврат Ответ;
Рассмотрим несколько правил проектирования HTTP-сервисов в 1С:
ПрочитатьJSON() и ЗаписатьJSON().