Использование REST web-сервисов в "1C:Предприятии 8". Личный опыт.
Когда мне понадобилось использовать REST сервисы в 1С, я столкнулся с "лаконичностью" имеющейся документации и минимумом реальных примеров. Данная статья основана, в первую очередь, на материалах фирмы 1С (http://its.1c.ru/db/metod8dev/content/3790/hdoc/_top/post и http://v8.1c.ru/o7/201312rest/ и https://wonderland.v8.1c.ru/blog/rasshirenie-podderzhki-protokola-odata/) и собственном опыте и призвана немного прояснить тему.
Итак, начнем сначала.
Что такое REST и зачем он нужен
REST (REpresentation State Transfer) подход является одним из наиболее популярных подходов, использующихся для реализации web-сервисов в Интернете. REST web-сервисы являются более легковесными альтернативами SOAP веб-сервисам.
REST с технической точки зрения не является ни технологией, ни стандартом. Это всего лишь подход, если можно так сказать, набор принципов, которые помогают реализовать "правильный" web-сервис. Под "правильным" здесь понимается масштабируемый, безопасный, надежный, легкий в использовании и т. д.
REST определяет следующие принципы построения web-сервисов:
- Функциональность приложения делится на набор ресурсов. Каждый ресурс может выполнять определенное действие (REST ресурс является аналогом SOAP операции). Например, ресурс получения новостей выдает список заголовков текущих новостей;
- Каждый ресурс имеет уникальный идентификатор (URL), по которому к нему можно обратиться как из программного кода, так и из Web-браузера;
- Все ресурсы используют унифицированный интерфейс для передачи данных между клиентом и ресурсом. Интерфейс имеет ограниченный набор операций и типов данных для передачи. Как правило, в качестве транспорта используется инфраструктура HTTP, а набор операций, которые можно выполнить над ресурсом, определяется HTTP стандартом. Наиболее используемыми операциями могут быть: HTTP GET - получение данных от ресурса и HTTP POST отправка данных в ресурс. Также могут использоваться HTTP PUT, HTTP DELETE и т. д.;
- REST протокол взаимодействия (RESTful) должен быть клиент-серверным и не иметь состояния.
Преимуществами REST подхода являются:
- Возможность работы на уже существующей HTTP инфраструктуре - Web-серверах, Web-браузерах и др.
- Простота использования и высокая совместимость между реализациями за счет того, что кодирование данных сведено к минимуму. Кодируются только прикладные данные (т. е. то, что нужно передать), вспомогательная маркировка данных (например, такая как soap:Envelope) не используется.
- Хорошая масштабируемость, т. к. REST протоколы не поддерживают состояния между вызовами.
- Хорошая безопасность, которая опять-таки основана на HTTP инфраструктуре.
Недостатки REST'а являются продолжением его достоинств:
- Сложно использовать вне HTTP, т. к. нет ни соответствующих стандартов, ни существующих реализаций.
- Сложно использовать в Entreprise решениях, где требуется поддержка достаточно сложного состояния (например, наличия сессий и др.).
- Полная зависимость от транспорта в таких вопросах, как безопасность, маршрутизация сообщений и пр., что может негативно сказаться на работе такого сервиса в гетерогенной среде.
Протокол, который основывается на принципах REST, является RESTful протоколом. Два наиболее популярных типа RESTful протоколов - это JSON (JavaScript Object Notation) и POX (Plain Old XML). JSON использует для кодирования данных JavaScript и в основном применяется в Ajax (Asynchronous JavaScript and XML) клиентах для обмена данными с сервером. Поскольку Ajax клиенты работают в браузере, который понимает JavaScript, то использование JavaScript позволяет сэкономить как на объеме передаваемых данных, так и на времени разбора данных. Однако использование JSON в других клиентах проблематично, т. к. клиенты, как правило, не поддерживают JavaScript.
POX использует для кодирования данных XML и поэтому может использоваться практически везде.
REST в 1С
Начиная с версии 8.3.5.1068. платформа может автоматически формировать REST интерфейс для всего прикладного решения. REST интерфейс позволяет читать данные 1С:Предприятия, изменять их, создавать новые объекты данных и удалять существующие. В качестве протокола доступа платформа использует протокол OData версии 3.0. Это открытый веб-протокол для запроса и обновления данных. Он позволяет оперировать данными, используя в качестве запросов HTTP-команды. Получать ответы можно в различных форматах, но пока платформа поддерживает только работу с данными в формате Atom/XML.
Использовать стандартный интерфейс OData прикладного решения просто:
- В конфигураторе вы публикуете REST интерфейс - флажок Публиковать стандартный интерфейс OData;
- После этого объекты прикладного решения становятся доступны через этот интерфейс;
- Способы аутентификации OData клиентов полностью совпадают со способами, используемыми для веб-сервисов;
- OData клиенты могут запросить через HTTP документ метаданных, описывающий доступные объекты прикладного решения;
- OData клиенты выполняют операции создания, чтения, модификации и удаления данных прикладного решения.
По умолчанию после публикации объекты конфигурации не доступны. Прежде чем обращаться к ним, необходимо разрешить доступ, например с помощью типовой обработки "Настройка автоматического REST сервиса". В обработке можно задать отдельного пользователя REST сервиса:
и указать доступные объекты конфигурации:
Чтение данных через REST
Чтение данных выполняется GET-запросом. Сначала устанавливаем HTTPСоединение с базой. Потом формируем текст запроса. Например, получение списка УИДов элементов справочника Контрагенты выглядит так:
/Base1C/odata/standard.odata/Catalog_Контрагенты?$select=Ref_Key&$format=json;odata=nometadata
Что означает это заклинание?
"Base1C" - имя базы, как оно опубликовано на веб-сервере,
"odata/standard.odata" - "магическое" слово, означающее доступ через odata интерфейс
"Catalog_Контрагенты" - состоит из указания на тип объекта "Catalog" - справочник и типа справочника
"select" - оператор чтения данных, после него через "=" идет описание считываемых данных, в данном случае это "Ref_Key" - уникальный идентификатор
"format=json" - задает формат представления считываемых данных JSON
"odata=nometadata" - заклинание, указывающее не передавать в ответе описание метаданных.
Из текста запроса создаем объект HTTPЗапрос:
Запрос = Новый HTTPЗапрос(СтрокаЗапроса);
и отправляем его:
Ответ = HTTPсоединение.Получить(Запрос);
Полученный объект HTTPОтвет надо разобрать, удобнее анализировать строку:
ОтветСтрокой = Ответ.ПолучитьТелоКакСтроку();
Если все хорошо, в ОтветСтрокой находится что-то вроде:
{
"value": [{
"Ref_Key": "a913b5c7-9594-4680-8013-e6a8ff2ef33e"
},{
"Ref_Key": "e29427d9-9cbb-421d-8089-e9859b2427c3"
},{
}
Разобрать ответ можно например так:
Если Ответ.КодСостояния > 299 Тогда
ТекстОшибки = "Error, код ошибки: " + Ответ.КодСостояния + "
|" + ОтветСтрокой;
Иначе
КолСтрок = СтрЧислоСтрок(ОтветСтрокой);
Для НомерСтроки=1 По КолСтрок Цикл
СтрокаАнализа = СтрПолучитьСтроку(ОтветСтрокой, НомерСтроки);
Если СтрНайти(СтрокаАнализа,"Ref_Key") > 0 Тогда
ПозицияДо = СтрНайти(СтрокаАнализа, """",НаправлениеПоиска.СКонца);
ПозицияС = СтрНайти(СтрокаАнализа, """Ref_Key"": """);
Если (ПозицияС > 0) И (ПозицияДо = (ПозицияС + 48)) Тогда
НачалоID = ПозицияС + 12;
GUID = Сред(СтрокаАнализа, НачалоID, 36);
РезультатМассив.Добавить(GUID);
КонецЕсли;
КонецЕсли;
КонецЦикла;
БулевРезФун = Истина;
ТекстОшибки = "OK. Считано элементов: " + Формат(РезультатМассив.Количество(), "ЧН=0; ЧГ=");
КонецЕсли;
Если нужно получить не один реквизит, текст запроса выглядит так:
/Base1C/odata/standard.odata/Catalog_Контрагенты?$select=Ref_Key,Description &$format=json;odata=nometadata
нужные поля добавляются через запятую в select.
Как правило все записи справочника читать не требуется, используем оператор filter:
СтрокаЗапроса = СтрокаЗапроса + "&$filter=Ref_Key eq guid'" + KeyID + "'";
где в KeyID строковое представление УИД
Наименование реквизитов как видите порой неочевидно. Необходимо запомнить:
Code - код,
DeletionMark - пометка удаления,
IsFolder - признак группы,
Parent_Key - родитель.
Если реквизит ссылочного типа, к его имени следует добавить суффикс _Key, например Организация_Key.
Для документов используется схожий синтаксис:
/Base1C/odata/standard.odata/Document_СчетНаОплатуПокупателю?$select=Ref_Key, Number, Date&$format=json;odata=nometadata
Для документов:
Number - номер документа,
Date - дата документа.
Создание и изменения объектов через REST будет в следующей части.