Стал замечать подобные решения давно, но у меня не было особого желания вступать в дискуссию, да и времени особо нет. С другой стороны, вижу, как безжалостно отдают чертежи бомб и с этим что-то надо делать. Затевал написать данную статью 2-3 года назад и вот выдался свободный денек, поэтому каюсь в содеянном… Надеюсь моя история кому-то послужит уроком.
О чем пойдет речь?
Речь пойдет о связке «Универсальных решений по обмену на http\web-сервисах» и методах «Выполнить\Вычислить». Хотя использование данных методов в файловых вариантах считаю еще большим злом (камень в огород конвертации данных).
Проблема на самом деле не только с интеграцией… Видел статью, к примеру по созданию «Универсального регламента» на доп. обработках, где из анонса было понятно, что редактирование кода выведено на форму, а код естественно хранится в реквизите ХранилищеНастроек(даже из названия реквизита понятно, что он затевался для других целей), а выполнение происходит в методе Выполнить(). Или выкладываются обработки\расширения, дающие возможность пользователям освоить программирование в клиентской части…
Сразу скажу я не против того, что эти методы есть и понимаю, что они позволяют делать. Использую сам, но...
1] Я за то, чтобы подобные решения были созданы как минимум после прочтения вот этой статьи: https://its.1c.ru/db/v8std#content:770:hdoc
Если кратко, то рекомендуется ограничить доступ пользователей к редактору кода, код выполнять в безопасном режиме, а в случае, когда это невозможно создать некий справочник, в котором хранить код, но доступ к этому справочнику на создание и изменение должен быть только у пользователя ответственного за безопасность.
2] Автор должен предупредить о возможных последствиях использования его решения!
Немного истории.
В начале 2017 года устроился в фирму, где очень долго экономили на IT, но поняли, что пора что-то менять, ибо движение пошло не вперед, а назад. Первым делом они решили спрыгнуть с франча(на то было масса причин) и набрать свой отдел 1С программистов и отдел администраторов. До этого момента я успел поучаствовать в двух проектах (УПП+Документооборот и ERP+Документооборот) и присоединился к команде замыкающим. Это была команда «Мечты» (я про отдел программистов имею ввиду), я рад что мне удалось поработать с такими людьми, хоть и всего полтора года. Был выполнен просто сумасшедший объем работы, был обмен опыта, в общем команда «Мечты». Потом вся команда разбежалась и в 2020 году удалось опять собрать часть этой команды на проект внедрения ERP-Общепит в очень сжатые сроки (Но это уже начало другой истории).
Какие были проблемы в 2017 году?
-Денег на расширения хранилища данных не выделяли, что привело к тому, что в основном каждый из команды тащил определенный проект. Грубо говоря 1 рабочая база и 1 тестовая, и так с каждой конфигурацией. Кто бухгалтерию переводил с 2 на 3, кто готовил УТ 10 к переходу на ERP, мне досталась розница для франшизы и написание http-сервисов для себя и вебера (Про свою часть проекта я рассказал на INFOSTART MEETUP Ekaterinburg.Online. 15 мая 2020 г., тема доклада: «Проект, который прошел путь от провала до web-клиента. От web-клиента до мобильного приложения.»).
-От франча достались ХАОС и Разруха… Все базы были сильно перепилены, самая популярная из них была УТ 10. В УТку я добавил универсальный http-сервис (на тот момент я его считал универсальным) и периодически в специально подготовленный модуль добавлял новые методы (принцип работы изложен в статьях из цикла «HTTP Сервисы: Путь к своему сервису»). Коллеги тоже стали использовать данный транспорт.
-Популярность УТ привела к эффекту «Макдональдса».
То и дело веберу или еще кому, был нужен новый http-сервис, а конфигуратор кем-то занят.
Мне пришла в голову мысль «Спасение утопающего дело рук утопающего»…
Реализация или как я изобрел динамит.
Первый вариант «Выполнятора» был накидан минут за 5-10, и я кайфовал, через неделю был добавлен «Выполнятор» второй версии, и я был доволен как удав. Вот оно! Легкое решение, облегчающее жизнь.
Я еще не знал, что через месяц проснусь по средь ночи с мыслями: -Что же ты натворил!!!
Так же как Нобель изобрел динамит и возненавидел свое изобретение, так и я отношусь к «Выполнятору»
Принцип работы.
Собственно, все просто как автомат Калашникова…
Посылаешь код и параметры в определенной структуре JSON и на стороне базы с данной структурой работает Выполнить()…
Плюсы есть, но минусов в разы больше!
Выкладываю код монстра!!! Не нужно его использовать!!!
Шаблон http-сервиса: /{ВхДанные}
Метод: POST
Функция HTTPServPOST(Запрос)
//Тут получаем имя метода, в нашем случае "Completer" или "CompleterParam"
перИмяМетода = Запрос.ПараметрыURL["ВхДанные"];
//Тут получаем код для выполнения и параметры
ЗапросОтКлиентаJSON = Запрос.ПолучитьТелоКакСтроку();
СтруктураОтвет = HTTPСервисыPOST.ОбработкаВходящихДанныхHTTP(ЗапросОтКлиентаJSON,перИмяМетода);
//Готовим ответ
Ответ = Новый HTTPСервисОтвет(СтруктураОтвет.КодОтвета);
Если СтруктураОтвет.Отработало Тогда
Ответ.УстановитьТелоИзСтроки(СтруктураОтвет.ДанныеОтвета,КодировкаТекста.UTF8);
Иначе
Ответ.УстановитьТелоИзСтроки(СтруктураОтвет.ТекстОшибки,КодировкаТекста.UTF8);
КонецЕсли;
Ответ.Заголовки.Вставить("Content-Type","text/html; charset=utf-8");
Возврат Ответ;
КонецФункции
Чтение запроса и возврат ответа
Функция ОбработкаВходящихДанныхHTTP(ЗапросОтКлиентаJSON,перИмяМетода) Экспорт
СтруктураОтвет = Новый Структура("ДанныеОтвета,Отработало,ТекстОшибки,КодОтвета","",Истина,"",200);
Если ВРег(перИмяМетода) = ВРег("Completer") Тогда
ЯВыполнятор(СтруктураОтвет,ЗапросОтКлиентаJSON);
ИначеЕсли ВРег(перИмяМетода) = ВРег("CompleterParam") Тогда
ЯВыполнятор_Параметры(СтруктураОтвет,ЗапросОтКлиентаJSON);
//... еще методы
Иначе
СтруктураОтвет.КодОтвета = 404;
СтруктураОтвет.ТекстОшибки = "Неизвестный метод!!!";
СтруктураОтвет.Отработало = Ложь;
СтруктураОтвет.ДанныеОтвета = "";
КонецЕсли;
Возврат СтруктураОтвет;
КонецФункции
//Сервис Выполнятор предназначен для получения данных, необходимо подавать код всего модуля.
Процедура ЯВыполнятор(СтруктураОтвет,ЗапросОтКлиентаJSON)
Попытка
//ЗапросОтКлиентаJSON = ЗапросОтКлиентаJSON + "
//| ЗаполнитьСтруктуруОтвета(СтруктураОтвет,200,"""",Истина,СтрокаJSON);";
Выполнить(ЗапросОтКлиентаJSON);
Исключение
перТекстОшибки = "Ошибка: "+ОписаниеОшибки();
ЗаполнитьСтруктуруОтвета(СтруктураОтвет,404,перТекстОшибки,Ложь,"X");
КонецПопытки;
КонецПроцедуры
//ЯВыполнятор_Параметры
Процедура ЯВыполнятор_Параметры(СтруктураОтвет,ЗапросОтКлиентаJSON)
//Читаем JSON
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ЗапросОтКлиентаJSON);
Попытка
ВХ_Структура = ПрочитатьJSON(ЧтениеJSON);
Исключение
ЗаполнитьСтруктуруОтвета(СтруктураОтвет,404,"Неудалось получить данные! Возможно не в JSON передаете!",Ложь,"X");
Возврат;
КонецПопытки;
Если ТипЗнч(ВХ_Структура) = Тип("Структура") Тогда
Если не ВХ_Структура.Свойство("ТекстКоманды") Тогда
ЗаполнитьСтруктуруОтвета(СтруктураОтвет,404,"В структуре отсутствует свойство ""ТекстКоманды""!",Ложь,"X");
Возврат;
КонецЕсли;
Если не ВХ_Структура.Свойство("вхПараметры") Тогда
вхПараметры = Новый Структура;
Иначе
вхПараметры = ВХ_Структура.вхПараметры;
КонецЕсли;
Иначе
ЗаполнитьСтруктуруОтвета(СтруктураОтвет,404,"Передана не структура!",Ложь,"X");
Возврат;
КонецЕсли;
Попытка
Выполнить(ВХ_Структура.ТекстКоманды);
Исключение
перТекстОшибки = "Ошибка: "+ОписаниеОшибки();
ЗаполнитьСтруктуруОтвета(СтруктураОтвет,404,перТекстОшибки,Ложь,"X");
КонецПопытки;
КонецПроцедуры
Процедура ЗаполнитьСтруктуруОтвета(СтруктураОтвет,КодОтвета,ТекстОшибки,Отработало,ДанныеОтвета)
СтруктураОтвет.КодОтвета = КодОтвета;
СтруктураОтвет.ТекстОшибки = ТекстОшибки;
СтруктураОтвет.Отработало = Отработало;
СтруктураОтвет.ДанныеОтвета = ДанныеОтвета;
КонецПроцедуры
Вот так я лишился сна!
Аргументы за и против.
+ Легко встроить и использовать.
+ Можно дорабатывать, не трогая головную конфигурацию.
- Постоянно пересылаешь весь код и параметры при работе с методом.
- Меняя, добавляя код в куче мест, не трогая главную конфигурацию, создается риск замены кода не везде где нужно.
- Чем больше мест подключения к главной конфигурации через данный костыль, тем больше времени на будущие доработки. Грубо говоря или менять код в главной базе или подстраиваться под изменения везде, где данное решение используется.
- Определенные сложности с оптимизацией процессов.
- Невозможность отладки такого кода
- Невозможность замера производительности такого кода
- Невозможность определять свои методы
- Вы вдруг уволитесь, переедете или не дай бог… Обслуживать будет кто-то другой. Поставьте себя на его место! Представьте, как ему потом разгребать ваш костыль.
- Есть вариант, что кто-то узнает про ваше решение и будет использовать в свое благо. Можно получать данные или передавать бомбы в виде неоптимального кода. А если у вас еще и не защищенное соединение, тогда посмотрите мультик «Трое из Простоквашино» про подмену посылки.
Можно еще нарисовать минусов, с плюсами сложнее…
Итог.
Дом нужно строить на нормальном фундаменте, а не на песке! Можно сделать универсальное решение и спать спокойно, но путь, который предполагает возить код для выполнения через транспорт – может испортить Вам сон!