Я уже писал статью с использованием HTTP-сервисов (Мобильный клиент + HTTP Сервис + Расширение конфигурации), но там было все сумбурно без объяснений, почему именно так. В данном цикле статей расскажу и покажу в примерах накопленный опыт в данном вопросе, и мы сделаем простой легко разворачиваемый каркас HTTP-сервиса.
Примеры будут сделаны в расширении конфигурации, на платформе 8.3.10.2650. Для опытов установил ERP 2.4.3.145(Но вообще непринципиально, ставим любую свежую конфигурацию под 8.3.10). Так как параллельно в свободное время веду разработку универсального решения под названием Pretty API или «PAPI», расширение будет содержать данную аббревиатуру.
Начнем.
Почему http-сервис?
А) HTTP сервисы на платформе 1С 8.3.5.1068 появились летом 2014 года, то есть 4 года назад, а Web-сервисы и того больше. Это кощунство не использовать их до сих пор.
Б) На Хабре в официальном блоге Фирмы 1С есть статья Способы интеграции с 1С от 25 августа 2016, почитайте ее, особенно в части устаревших технологий.
В) Геморрои с разными версиями и «comcntr.dll» забываем как страшный сон! Опубликовали и пользуемся, плюсом мы получаем Веб клиент, мобильный клиент, легкое использование нашего сервиса другими программистами (собственно, API) и другие пряники.
Г) Скорость! Использую Com последние 3 года только для того чтобы показать сравнение со стандартным интерфейсом oData или http-сервисом. Когда люди видят вживую, они даже иной раз не верят, что обмен прошел!
Это все равно, что ездить каждый год на поезде по 3 суток в сторону Сочи и вдруг слетать на самолете за 2,5 часа.
!!! Использование технологии COM (доступно только на платформе Windows) !!!
Д) С версии 8.3.7.1759 могут быть встроены через расширение, а с версии 8.3.9 плюсом к ним можно встроить модули для более простой работы с ними.
E) Простота и гибкость разработки.
Ж) Стагнация - это плохо! В работе можешь не использовать, но быть всегда готов. Нельзя стоять на месте, если пошел в IT сферу.
Еще много чего можно перечислить. Минусы, тоже есть, но плюсов в разы больше.
Самый главный минус. Нужно установить и настроить веб сервер (IIS, Apache, 1С: Публикатор или 1С: Линк – Apache с интерфейсом для простого пользователя). Тут вот в чем проблема: чаще всего администраторы почему-то не в состоянии это сделать, и приходится настраивать самому, либо они тупо устанавливают по дефолту и там начинаются пляски с бубном. Благо сейчас статей по настройки пруд пруди, ниже приведу парочку загугленных:
Пошаговая инструкция настройки web-сервисов для 1Сv8.3 и IIS 8.5, в данной инструкции особенно выделю пункт 8.
Настройка веб сервера Apache + 1С (Пошаговое руководство)
Лично я использую IIS, но на вкус и цвет как говорится.
Ближе к делу.
Создадим демо конфигурацию для опытов и добавим в него расширение. Можно создавать все объекты и не в расширении, я просто показываю вариант без изменения конфигурации. (В расширении добавление HTTP-сервисов появилось с версии 8.3.7.1759.)
Давайте перед созданием нашего HTTP-сервиса разберемся из чего складывается URL (подробнее описано на ИТС в главе 17.2.2. HTTP-сервисы):
http://host/base/hs/корневойURL/относительныйURL?ПараметрыЗапроса
host – IP адрес или доменное имя веб сервера.
base – Имя базы. Указывается при публикации.
hs - признак того, что выполняется обращение к HTTP-сервису.
корневойURL - имя ресурса, которое определяет группу ресурсов, связанных общим смыслом.
относительныйURL - определяет ресурс, к которому будет выполняться обращение. Относительный URL, указанный в запросе, будет использован для определения конкретного ресурса, к которому выполнялось обращение. Правило сопоставления задается в объекте Шаблон URL.
ПраметрыЗапроса – Не всегда обязательные параметры передаются после знака «?», чаще всего дополнительные параметры или параметры выборки, например формат ответа(format=json или format=atom).
Теперь по порядку:
Создаем сервис и задаем ему корневойURL:
Создаем Шаблон URL:
При создании шаблона можно использовать следующие символы:
Любые символы, допустимые в идентификаторах языка «1С:Предприятие».
Символ «/»;
Символы «{}» с непустым текстом между ними;
Символ *.
Наш шаблон выглядит следующим образом: /V1/{ИмяМетода}
Где {ИмяМетода} является параметром. Параметр может состоять из букв, цифр и символа подчеркивания «_».
Почему такой шаблон?
Когда смотришь различные примеры, коих очень много в шаблоны запихивают параметры. Создают по несколько методов с разными параметрами. А зачем так делать?
Вот пример с ИТС (17.2.2.3.2. Работа с документами):
Видно, что создано два Шаблона с методом Get, но по большому счету отличаются они только тем, что один ищет по номеру документ, а второй выводит все.
Все это можно реализовать одним методом, список или документ подавать в параметр ИмяМетода, а дополнительными параметрами передавать номер. А давайте сделаем!
Добавляем метод GET.
Берем код из примера ИТС.
Функция СписокGET(Запрос)
Ответ = Новый HTTPСервисОтвет(200);
Результат = "Расходная накладная, 1, 01.01.2014
|Расходная накладная, 2, 01.01.2014";
Ответ.УстановитьТелоИзСтроки(Результат);
Возврат Ответ;
КонецФункции
Функция ДокументGET(Запрос)
Ответ = Новый HTTPСервисОтвет(200);
Номер = Число(Запрос.ПараметрыURL.Получить("number"));
Если Номер > 2 Тогда
Ответ.КодСостояния = 404;
Ответ.УстановитьТелоИзСтроки("Отсутствует документ с номером: " + Номер);
Иначе
Если Номер=1 Тогда
Ответ.УстановитьТелоИзСтроки("Расходная накладная, 1, 01.01.2014");
Иначе
Ответ.УстановитьТелоИзСтроки("Расходная накладная, 2, 01.01.2014");
КонецЕсли;
КонецЕсли;
Возврат Ответ;
КонецФункции
Видоизменяем его и добавляем код обработки метода:
Функция PrettyAPIGET(Запрос)
Ответ = Новый HTTPСервисОтвет(200);
ИмяМетода = Запрос.ПараметрыURL.Получить("ИмяМетода");
Если ИмяМетода = "Список" Тогда
Результат = "Расходная накладная, 1, 01.01.2014
|Расходная накладная, 2, 01.01.2014";
ИначеЕсли ИмяМетода = "Документ" Тогда
//ПраметрыЗапроса - number
ПарНомер = Запрос.ПараметрыЗапроса.Получить("number");
Номер = Число(?(ПарНомер=Неопределено,0,ПарНомер));
Если Номер > 2 Тогда
Ответ.КодСостояния = 404;
Результат = "Отсутствует документ с номером: " + Номер;
Иначе
Если Номер = 1 Тогда
Результат = "Расходная накладная, 1, 01.01.2014";
Иначе
Результат = "Расходная накладная, 2, 01.01.2014";
КонецЕсли;
КонецЕсли;
Иначе
Ответ.КодСостояния = 405;
Результат = "Отсутствует Метод " + ИмяМетода;
КонецЕсли;
Ответ.УстановитьТелоИзСтроки(Результат,КодировкаТекста.UTF8);
//Ответ.Заголовки.Вставить("Content-Type","text/html; charset=utf-8");
Возврат Ответ;
КонецФункции
Выполняем публикацию нашего сервиса:
Проверяем результат:
1 Получим список. Запрос: http://127.0.0.1/DemoEnterprise2_4_3_145/hs/PrettyAPI/V1/Список
Результат:
Получаем какие-то «кракозябры»! Первый раз я нарвался на этот момент с кодировкой около 4-х лет назад, ну и так как на ИТС пример как раз приводит к этому, решил показать и рассказать, как исправить.
Вы обратили внимание, что в коде функции PrettyAPIGET я оставил в самом конце закомментированную строку
//Ответ.Заголовки.Вставить("Content-Type","text/html; charset=utf-8");
Разкомментируем ее и проверим, как теперь отработает наш сервис.
2 Получим документ с номером 1. Запрос: http://127.0.0.1/DemoEnterprise2_4_3_145/hs/PrettyAPI/V1/Документ?number=1
Результат:
Важно: хотелось бы обратить внимание на коды состояния из примера выше. Мне раза три в моей практике попадались API, которые всегда возвращали ответ с кодом 200 (200 OK («хорошо»)) и только в теле ответа, можно было понять, была ли ошибка. Это грубейшая ошибка разработчиков! Ну или это неуважение к конечному потребителю...
Передавая ответ, не забывайте про коды состояния (Список кодов состояния)!
Вот тут хороший пример по работе с ответом в зависимости от кода состояния, обратите внимание на ошибку с кодами 3XX.
Как Вы видите, мы обошлись одним Шаблоном для той же задачи. По сути можно сделать некий универсальный каркас для HTTP-метода и решать любую задачу Интеграции.
Давайте разобьем все возможные сервисы на блоки, чтобы понять, как сделать некое универсальное решение.
Сервис выполняет следующие действия:
- Получение входящих параметров и проверка их корректности
- Выполнение основных действий
- Формирование ответа
Если посмотреть пример выше, то понимаем, что все идет в вперемешку, не структурированно. Отлаживать такой сервис не очень приятно!
Я предпочитаю для HTTP-методов создавать отдельные модули и «Выполнение основных действий» осуществлять в созданном модуле. Создание отдельного модуля позволяет отлаживать HTTP-сервис через внешнюю обработку, это бывает необходимо при получении ошибки, которая говорит, что в коде есть ошибка, но отладка по HTTP не останавливается на точке остановы. Давайте «причешем» пример выше.
Создадим модуль и переделаем «получение параметров» и «формирование ответа».
Функция PrettyAPIGET(Запрос)
СтруктураВхПараметров = Новый Структура;
//Получаем имя метода
перИмяМетода = Запрос.ПараметрыURL["ИмяМетода"];
//Помещаем имя метода в структуру
СтруктураВхПараметров.Вставить("ИмяМетода",перИмяМетода);
//Забираем параметры из запроса
ВхПараметрыЗапроса = Новый Соответствие;
Для каждого Параметр Из Запрос.ПараметрыЗапроса Цикл
ВхПараметрыЗапроса.Вставить(Параметр.Ключ,Параметр.Значение);
КонецЦикла;
СтруктураВхПараметров.Вставить("ПараметрыЗапроса",ВхПараметрыЗапроса);
//Передаем входящие параметры (Модуль для метода GET)
СтруктураОтвет = PAPI_ОбработкаМетодовGET.PAPI_ОбработкаМетодовGET(СтруктураВхПараметров);
//Создаем ответ с кодом состояния
Ответ = Новый HTTPСервисОтвет(СтруктураОтвет.КодОтвета);
Если СтруктураОтвет.Отработало Тогда
Ответ.УстановитьТелоИзСтроки(СтруктураОтвет.ДанныеОтвета,КодировкаТекста.UTF8);
Иначе
Ответ.УстановитьТелоИзСтроки(СтруктураОтвет.ТекстОшибки,КодировкаТекста.UTF8);
КонецЕсли;
Ответ.Заголовки.Вставить("Content-Type","text/html; charset=utf-8");
Возврат Ответ;
КонецФункции
//Функция экспортная, специально чтобы можно было отлаживать как по HTTP(https://its.1c.ru/db/metod8dev#content:5756:hdoc)
//Так и через внешнюю обработку
Функция PAPI_ОбработкаМетодовGET(СтруктураВхПараметров) Экспорт
//структура ответа. Собственна нужна для формирования ответа
СтруктураОтвет = Новый Структура("ДанныеОтвета,Отработало,ТекстОшибки,КодОтвета","",Истина,"",200);
//Переправляем на нужный метод
Если ВРег(СтруктураВхПараметров.ИмяМетода) = ВРег("Список") Тогда
ПолучитьСписок(СтруктураОтвет,СтруктураВхПараметров);
ИначеЕсли ВРег(СтруктураВхПараметров.ИмяМетода) = ВРег("Документ") Тогда
ПолучитьДокумент(СтруктураОтвет,СтруктураВхПараметров);
Иначе
ЗаполнитьСтруктуруОтвета(СтруктураОтвет,405,"Отсутствует Метод " + ?(СтруктураВхПараметров.ИмяМетода=Неопределено,"",СтруктураВхПараметров.ИмяМетода),ложь,"");
КонецЕсли;
Возврат СтруктураОтвет;
КонецФункции
//Заполняем структуру ответа
Процедура ЗаполнитьСтруктуруОтвета(СтруктураОтвет,КодОтвета,ТекстОшибки,Отработало,ДанныеОтвета)
СтруктураОтвет.КодОтвета = КодОтвета;
СтруктураОтвет.ТекстОшибки = ТекстОшибки;
СтруктураОтвет.Отработало = Отработало;
СтруктураОтвет.ДанныеОтвета = ДанныеОтвета;
КонецПроцедуры
//МЕТОДЫ
Процедура ПолучитьСписок(СтруктураОтвет,СтруктураВхПараметров)
Результат = "Расходная накладная, 1, 01.01.2014
|Расходная накладная, 2, 01.01.2014";
СтруктураОтвет.ДанныеОтвета = Результат;
КонецПроцедуры
Процедура ПолучитьДокумент(СтруктураОтвет,СтруктураВхПараметров)
//ПраметрыЗапроса - number
ПарНомер = СтруктураВхПараметров.ПараметрыЗапроса.Получить("number");
Номер = Число(?(ПарНомер=Неопределено,0,ПарНомер));
Если Номер > 2 Тогда
ЗаполнитьСтруктуруОтвета(СтруктураОтвет,404,"Отсутствует документ с номером: " + Номер,ложь,"");
Иначе
Если Номер = 1 Тогда
Результат = "Расходная накладная, 1, 01.01.2014";
Иначе
Результат = "Расходная накладная, 2, 01.01.2014";
КонецЕсли;
СтруктураОтвет.ДанныеОтвета = Результат;
КонецЕсли;
КонецПроцедуры
Как вы видите, размер кода увеличился, но стало гораздо проще добавлять новые методы.
Нужно просто добавить в проверку (PAPI_ОбработкаМетодовGET.PAPI_ОбработкаМетодовGET) новое имя метода и процедуру для этого метода.
По отладке HTTP-сервисов рекомендую статью с ИТС (https://its.1c.ru/db/metod8dev#content:5756:hdoc)
Первую часть заканчиваю. Мы рассмотрели с Вами как создать каркас для Get метода. В следующих частях поговорим про другие методы, про oData и JSON. Как и в этой статье будут примеры, но более интересные.
Статьи из данного цикла:
HTTP Сервисы: Путь к своему сервису. Часть 2
HTTP Сервисы: Путь к своему сервису. Часть 3
HTTP Сервисы: Путь к своему сервису. Часть 4
Также рекомендую: