Более года назад я начал работать в компании, в которой разработчики работали с конфигурациями 1С в режиме совместимости еще 8.2.16 (менять режим совместимости в типичных базах мы не хотели) — а как Вы наверное знаете, если интересовались HTTP-сервисами в 1С, их использование в режиме совместимости 8.3.4 и ниже недопустимо — и здесь я уже не надеялся на разработку и использование HTTP-сервисов.
Но позже меня заинтересовал такой «сервис» как REST интерфейс OData, так как его можно использовать не меняя режим совместимости конфигурации — именно он и стал для меня идеальным вариантом решения «нетривиальных» задач.
Итак, начиная с версии платформы 8.3.5 в 1С появился REST интерфейс OData. Подробнее о его реализацию можно почитать на Зазеркалье 1С и закрытом разделе ИТС.
В двух словах, REST это способ взаимодействия с помощью HTTP запросов. OData это стандарт описывающих формат ЭТИХ запросов и ответов на них.
Для работы с ним достаточно установить флажок "публиковать стандартный интерфейс OData" при публикации конфигурации на web-сервер (смотрите ниже).

&НаСервере
Процедура УстановитьODataНаСервере()
тМассив = Новый Массив;
тМассив.Добавить(Метаданные.Справочники.ФизическиеЛица);
УстановитьСоставСтандартногоИнтерфейсаOData(тМассив);
КонецПроцедуры
Если ОбменССерверомСбораДанных.СоединенияССерверомСбораДанныхУстановлено() Тогда
ОбменССерверомСбораДанных.ОтправитьНаСерверСбораДанных(ЭтотОбъект.Ссылка, , 1);
КонецЕсли;
Функция СоединенияССерверомСбораДанныхУстановлено() Экспорт
Возврат (НЕ Константы.СерверСбораДанныхДляЗарплатнойСистемы.Получить() = "");
КонецФункции
Далее опишу метод отправки пока только справочника, если будет спрос — будет и продолжения статьи (по обмену документов и регистров).
Вот общая процедура отправки данных на сервер — ОтправитьНаСерверСбораДанных ():
Процедура ОтправитьНаСерверСбораДанных(СсылкаИсточник, DELETE = Ложь, ТипОбъекта = 0) Экспорт
Итак, самое интересное:
1) Функция СправочникДоставленоУспешно (СсылкаСправочник, DELETE, Метод = "POST", Тень = Ложь)
СсылкаСправочник — ссылка справочника
DELETE — булево — удаление на сервере сбора данных по GUID
Метод — строка — по умолчанию — "POST" (о других методах тоже достаточно материалов в свободном доступе)
Тень — булево — если функцию использует регламентное задание, этот параметр будет истина.
Функция СправочникДоставленоУспешно(СсылкаСправочник, DELETE, Метод = "POST", Тень = Ложь)
Функция СправочникДоставленоУспешно(СсылкаСправочник, DELETE, Метод = "POST", Тень = Ложь)
Если Константы.СерверСбораДанныхОфлайн.Получить() И (НЕ Тень) Тогда // если связи нету можна просто перейти в офлайн используя Константы.СерверСбораДанныхОфлайн.Установить(Истина)
Возврат Ложь;
КонецЕсли;
Связь = ПолучитьКаналСвязиССерверомСбораДаних(); // служебное - смотри далее
ИмяСправочника = СсылкаСправочник.Метаданные().Имя;
Если Тень Тогда
// теневые копию я создавал в идентичном обьъкте как оригинальний справочник, только с префиксом «_с_». Зачем? Запрос по теневым копиям работают быстрее, и в случае успешной доставки теневой копию — копия удалялась
ИмяСправочника = СтрЗаменить(ИмяСправочника,"_с_","");
КонецЕсли;
guid = Строка(СсылкаСправочник.УникальныйИдентификатор());
Если DELETE Тогда // если удалить объект
АдресРесурса = "/" + Связь.Порт + "/odata/standard.odata/Catalog_" + ИмяСправочника + "(guid'"+ guid + "')";
Соединение = Новый HTTPСоединение(Связь.Сервер);
ЗаголовокHTTP = Новый Соответствие();
ЗаголовокHTTP.Вставить("Accept", "application/atom+xml,application/xml");
ЗаголовокHTTP.Вставить("Accept-Charset", "UTF-8");
ЗаголовокHTTP.Вставить("DELETE" + " /" + Связь.Порт + "/odata/standard.odata/Catalog_" + ИмяСправочника + "(guid'"+ guid + "')");
ЗаголовокHTTP.Вставить("Content-Type", "application/atom+xml");
ЗаголовокHTTP.Вставить("DataServiceVersion", "3.0;NetFx");
ЗаголовокHTTP.Вставить("MaxDataServiceVersion", "3.0;NetFx");
ЗаголовокHTTP.Вставить("User-Agent", "1C-Enterprise");
ЗаголовокHTTP.Вставить("Host", Связь.Сервер);
Запрос = Новый HTTPЗапрос(АдресРесурса, ЗаголовокHTTP);
Ответ = Соединение.ВызватьHTTPМетод("DELETE", Запрос);
Возврат Ответ.КодСостояния = 204 // случае успешного удаления сервер вернет код состояния =204
Иначе // если создать/обновить объект
АдресРесурса = "/" + Связь.Порт + "/odata/standard.odata/Catalog_" + ИмяСправочника + ?(Метод = "PUT", "(guid'" + guid + "')","");
ТекстЗапроса = ОпределитьШапкуЗапроса(guid); // служебное - смотри далее
// соответствие стандартных реквизитов
CписокCтандартныхРеквизитов = СоздатьОписанияОбязательнихРеквизитовСправочника(СсылкаСправочник); // служебное - смотри далее
Для Каждого ОписаниеРеквизита ИЗ CписокCтандартныхРеквизитов Цикл
ТекстЗапроса = ТекстЗапроса + "
| <d:" + ОписаниеРеквизита.Ключ + ">" + СокрЛП(ОписаниеРеквизита.Значение) + "</d:" + ОписаниеРеквизита.Ключ + ">";
КонецЦикла;
// соответствие дополнительных реквизитов
СписокДопРеквизитов = СоздатьОписанияДополнительнихРеквизитов(СсылкаСправочник); // служебное - смотри далее
Для Каждого ОписаниеДопРеквизита ИЗ СписокДопРеквізитів Цикл
ТекстЗапроса = ТекстЗапроса + "
| <d:" + ОписаниеДопРеквизита.Ключ + ">" + СокрЛП(ОписаниеДопРеквизита.Значение) + "</d:" + ОписаниеДопРеквизита.Ключ + ">";
КонецЦикла;
// соответствие табличных частей
ОписаниеТабличныхЧастей = СоздатьОписанияТабличныхЧастей(СсылкаСправочник, "Catalog", Тень); // служебное - смотри далее
Если НЕ ОписаниеТабличныхЧастей = "" Тогда
ТекстЗапроса = ТекстЗапроса + ОписаниеТабличныхЧастей;
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + "
| </m:properties>
| </content>
|</entry>";
Соединение = Новый HTTPСоединение(Связь.Сервер);
Заголовки = Новый Соответствие;
Заголовки.Вставить("Accept", "application/atom+xml,application/xml");
Заголовки.Вставить("Accept-Charset", "UTF-8");
Заголовки.Вставить(Метод + " /" + Связь.Порт + "/odata/standard.odata/Catalog_" + ИмяСправочника + ?(Метод = "PUT", "(guid'" + guid + "')","") + " HTTP/1.1");
Заголовки.Вставить("Content-Type", "application/atom+xml");
Заголовки.Вставить("DataServiceVersion", "3.0;NetFx");
Заголовки.Вставить("MaxDataServiceVersion", "3.0;NetFx");
Заголовки.Вставить("User-Agent", "1C-Enterprise");
Заголовки.Вставить("Host", Связь.Сервер);
Попытка
Запрос = Новый HTTPЗапрос(АдресРесурса, Заголовки);
Запрос.УстановитьТелоИзСтроки(ТекстЗапроса);
Ответ = Соединение.ВызватьHTTPМетод(Метод, Запрос);
Если (Ответ.КодСостояния <> 201) И (Метод = "POST") Тогда // успешным для POST считается код 201
Возврат СправочникДоставленоУспешно(СсылкаСправочник, DELETE,"PUT", Тень);
ИначеЕсли (Ответ.КодСостояния <> 200) И (Метод = "PUT") Тогда // успешным для PUT считается код 200
Возврат Ложь
Иначе
Возврат Истина
КонецЕсли;
Исключение
Возврат Ложь;
КонецПопытки;
КонецЕсли;
КонецФункции
И, конечно, список функций обозначенных комментарием "служебное":
Функция ПолучитьКаналСвязиССерверомСбораДаних()
Функция СоздатьОписанияДополнительнихРеквизитов(СсылкаОбъекта, СписокСсылочных = 0)
Функция СоздатьОписанияТабличныхЧастей(СсылкаОбъекта, ПрефиксОбъекта, Тень = Ложь)
Функция НормализироватьКОбмену(ЭтотРеквизит)
Функция ОпределитьШапкуЗапроса(GUID = "00000000-0000-0000-0000-000000000000")
Функция СоздатьОписанияОбязательнихРеквизитовСправочника(СсылкаСправочник)





Во вступлении к статье ошибка — использовать HTTP-сервисы можно в любом режиме совместимости.
Ограничение на использование в режиме совместимости было только в версии 8.3.7. Смотрите V8Update для версии 8.3.8
(1) «Для конфигураций, в которых используются HTTP-сервисы, разрешена установка режима совместимости Версия 8.3.4 и ниже.
При необходимости работать с конфигурацией, которая содержит HTTP-сервисы, на системе «1С:Предприятие» версии 8.3.8 и выше, но которая открывалась конфигуратором системы «1С:Предприятие» версии 8.3.4, необходимо выполнить следующие действия:
Создать любой объект конфигурации;
Выполнить сохранение конфигурации информационной базы;
Удалить созданный объект конфигурации;
Выполнить сохранение конфигурации информационной базы.»
понял) попробуем сделать действия которые там описанные. но главный акцент статьи все таки это Rest OData
После выхода продолжения, не забудь те в этой статье вставить ссылку на продолжение
(4)
(0) код не читаем(не глагол)
(8) спасибо, будет исправлено!
Синхронный обмен через сервисы выглядит плохой идеей. Возможны большие задержки, юзеры будут смотреть на «зависший» 1с и нервничать. Переделайте отправку на асинхронный режим через фоновые задания.
(8) если менять пакеты данных — то да; но у нас один элемент справочника — одна «отправка» в другую базу; ответ приходит моментально; и уже в зависимости от ответа — если он отрицательный, то оставляем на «переотправку» фоновому заданию
(9) Помимо размера отправляемых данных надо учитывать кол-во юзверей. Помимо задержек при транспорте есть ожидания на блокировках. Сейчас их у вас нет, завтра система вырастет вширь и они появятся.
(10) да, согласен, пока проблем нет; тогда в базе приемнике будем дописывать «очередь», чтобы избежать блокировок (и тут уже неважно как «направляются» данные туда — или онлайн, или фоново)
да, согласен, пока проблем нет; тогда в базе приемнике будем дописывать «очередь», чтобы избежать блокировок (и тут уже неважно как «направляются» данные туда — или онлайн, или фоново)