Зарисовки на тему оформления кода HTTP-сервиса 4. Контроллер

15.07.26

Интеграция - WEB-интеграция

Заключительная статья на тему взаимосвязей модулей http-сервиса и приемов оформления кода. Еще раз про слои и разделение функций между ними. Контроллер как владелец бизнес-логики, преобразователь данных. Примеры кода на базе пет-проекта «Управление задачами».

Начало: Слои и модуль СервисаВалидация данных, Провайдер данных

В прошлых статьях, мы выяснили, что можем подходить к разработке модулей сервиса независимо. У нас отсутствуют циклические зависимости модулей, нет взаимного вызова друг друга.

Контроллер занимает центральное место в сервисе, отвечает на команды модуля сервиса, может изменить предложенный код состояния и добавить заголовки ответа.

 

 

Еще раз о всех слоях и их взаимодействие с Контроллером.

 

Модуль Сервиса вызывает Контроллер и ничего не знает о модулях: Валидации данных, Провайдере данных.

  • Передает в параметрах методов Контролера: данные http-запроса и ссылку на КодОшибки.

  • Некоторые http-методы, могут потребовать дополнительные заголовки или специфический код состояний, тогда в параметры методов Контроллера добавляются ссылки на заголовки и код состояния.

  • Ожидает получить конкретные данные или не пустой КодОшибки.

  • Не содержит вызовов встроенных подсистем.

  • При необходимости может собирать тексты ошибок из пула ошибок и делать запись в журнал регистрации.

  • Формирует код состояния ответа (он либо заранее известен, либо зафиксирован в описании ошибки, либо возвращается из метода Контроллера по ссылке).

  • Формирует заголовки: типа содержимого, добавляет в заголовок Location, текст ошибки при необходимости переадресации.

  • В свою очередь Модуль Контроллера не знает о Модуле Сервиса.

 

Модуль Валидации данных, ничего не знает о сервисе, о БД.

  • Выполняет команды Контроллера по проверке входящих данных.

  • Проверка может быть точечная или массовая.

  • Для массовой проверки содержит в интерфейсе структуру правил и условий, которую Контроллер использует для подготовки наборов проверок.

  • Формирует сообщения пользователя о возникших ошибках при проверках. Тексты ошибок получает от Контроллера напрямую или в наборах правил/условий.

 

Модуль Провайдер данных содержит логику доступа к данным БД, для создания новых объектов БД и ничего не знает о сервисе.

  • Выполняет команды Контроллера и возвращает сырые данные из БД.

  • Предоставляет конструкторы для подготовки параметров доступа к данным и параметров для создания новых объектов, которые Контроллер должен заполнить

 

Модуль Контроллера содержит бизнес-логику сервиса, знает о существовании модулей Валидации и Провайдере данных, о входящих данных и формате выходящих. Его задачи:

  • Выполнить команды от модуля Сервиса, на выходе конкретные данные или Неопределено с заполненным КодОшибки

  • Формирует соответствие(связь) между входными и выходными параметрами.

  • Проверить специфические входящие данные: ожидаемые заголовки (и их значения), формат тела запроса и состав содержимого.

  • Дать команду модулю ВалидацияДанных проверить входящие данные, передав текст ошибки, который необходимо поместить в пул ошибок при негативной проверке

  • По завершению проверки входящих данных принимает решение о продолжении или заполняет КодОшибки

  • Дать команду модулю Провайдер данных получить данные из БД или создать новые объекты, передав преобразованные входящие данные

  • Преобразовать ответ от Провайдера данных в форму, которую ожидает модуль Сервиса или заполнить КодОшибки

  • При необходимости изменить полученные по ссылке Код и добавить Заголовки ответа.

 

Соответствие (связь) между входными и выходными параметрами

В статье о модуле Валидации, раздел Массовая проверка, мы рассматривали пример получения списка задач. Задачи получаем порциями, на задачи может быть наложен фильтр. Какой способ пагинации выбран и какой установлен фильтр мы узнаем из параметров запроса.

 

Функция СписокЗадачСоответствиеКлючей()

    Результат = Новый Соответствие;
    
    Результат.Вставить("ДатаНачала", "startDate");
    Результат.Вставить("ДатаОкончания", "endDate");
    Результат.Вставить("ИдентификаторИсполнителя", "userId");
    Результат.Вставить("ИдентификаторАвтора", "authorId");
    Результат.Вставить("НомерСтраницы", "page");
    Результат.Вставить("ДоКурсора", "before");
    Результат.Вставить("ПослеКурсора", "after");
    Результат.Вставить("Лимит", "limit");
    
    Возврат Результат;
КонецФункции

 

Ключи в этой структура – параметры доступа к данным, а значения – параметры входных данных, которые мы получаем из http-запроса (Запрос.ПараметрыЗапроса). Эта структура, вместе с наборами правил и условий будет передана в метод, который проверит по ним (наборам) входящие данные:

 

ПараметрыЗапроса = ВалидацияДанных.РезультатВалидации(
    Запрос.ПараметрыЗапроса,
    СписокЗадачСоответствиеКлючей(),
    НаборПравилВалидацииПараметровСпискаЗадач(),
    НаборУсловийПараметровСпискаЗадач(),
    Отказ
);

 

Отказ в Истина на выходе, будет означать, что проверка провалилась. Результатом будет структура, ключи – параметры доступа, значения – полученные из запроса и проверенные данные.

Окончательный вид параметры доступа приобретут, когда Контроллер запросит структуры для фильтра, для настройки получения и сопоставит с тем, что пришло и прошло проверку:

 

ФильтрЗадач = РаботаСЗадачамиРеализация.НовыйФильтрЗадач();
ЗаполнитьЗначенияСвойств(ФильтрЗадач, ПараметрыЗапроса);
…
НастройкиПолученияЗадач = РаботаСЗадачамиРеализация.НовыеНастройкиПолученияЗадач();
ЗаполнитьЗначенияСвойств(НастройкиПолученияЗадач, ПараметрыЗапроса);

 

 
 Конструкторы для подготовки параметров доступа от Провайдера

 

Список задач получаем в сыром виде, как выгрузку:

 

ДанныеЗадач = РаботаСЗадачамиРеализация.СписокЗадачВыгрузка(НастройкиПолученияЗадач, ФильтрЗадач, ЗадачНаСтраницу);
...
// Контроллер ничего не знает о встроенных подсистемах, поэтому за этим тоже обращаемся к Провайдеру данных
ДанныеЗадач = РаботаСЗадачамиРеализация.ТаблицаЗначенийВМассив(ДанныеЗадач);
...

Возврат ПодготовленныеЗадачи(ДанныеЗадач, ФайлыЗадач);

 

Сырые данные из БД и данные, которые ждет Сервис разные. Подготовка также через соответствие:

 

Функция СвойстваЗадачиСоответствие()

    Результат = Новый Соответствие;
    Результат.Вставить("УникальныйИдентификатор", "ID");
    Результат.Вставить("Номер", "TaskID");
    Результат.Вставить("Приоритет", "Priority");
    Результат.Вставить("Содержание", "Text");
    Результат.Вставить("Исполнитель", "UserID");
    Результат.Вставить("Автор", "AuthorID");
    
    Возврат Результат;
КонецФункции

Функция ПодготовленныеЗадачи(ДанныеЗадач, ФайлыЗадач = Неопределено)

    Результат = Новый Массив;
    Соответствие = СвойстваЗадачиСоответствие(); // через соответствие!
    
    Для Каждого СвойстваОбъекта Из ДанныеЗадач Цикл
        
        Приемник = Новый Структура;
        
        Для каждого Источник Из Соответствие Цикл
            
            Приемник.Вставить(Источник.Значение, СвойстваОбъекта[Источник.Ключ]);
        КонецЦикла;
        
        Ключ = Соответствие.Получить("Приоритет"); // особое свойство
        Значение = Неопределено;
        Если Приемник.Свойство(Ключ, Значение) Тогда
            
            Приемник.Вставить(Ключ, ПриоритетЗадачиИзОбъекта(Строка(Значение)))
        КонецЕсли;
        
        Если ФайлыЗадач <> Неопределено Тогда
            
            Файлы = ФайлыЗадач[СвойстваОбъекта.Ссылка];
            
            Приемник.Вставить("Файлы", ?(Файлы = Неопределено, Новый Массив, Файлы));
        КонецЕсли;
        
        Результат.Добавить(Приемник);
    КонецЦикла;
    
    Возврат Результат
КонецФункции

 

Создание новой задачи

Еще один пример – создание задачи, данные задачи могут прийти как JSON, или как поля формы. Результат может быть перенаправлен.

  • проверить тип содержимого и целостность данных – контроль заголовков и их значений

  • по конструктору НовыеСвойстваЗадачи() сопоставить с входящими данными:

 
 СвойстваЗадачи = НовыеСвойстваЗадачи();

      ЗаполнитьЗначенияСвойств(СвойстваЗадачи, ВходящиеСвойстваЗадачи);

  • получить параметры заполнения:

 
 РаботаСЗадачамиРеализация.ЗадачаСотрудникаПараметрыЗаполнения();
  • заполняя параметры заполнения проверять их корректность, пример:

 
 ПараметрыЗаполнения.Исполнитель = ПользовательПоИдентификатору(СвойстваЗадачи.UserID, Отказ);
  • проверку обязательности ключевых реквизитов доверить БД, результат отследить через Отказ и через заполнение СвойстваЗадачи.TaskID:

 
 РаботаСЗадачамиРеализация.СоздатьЗадачуСотрудника(ПараметрыЗаполнения, СвойстваЗадачи.TaskID, Отказ);
  • при необходимости указать на перенаправление: дополнить заголовком и изменить код

 

Вызов из модуля Сервиса, рассмотрен полностью в статье о модуле Сервиса:

КодОшибки = ""; Код = 201;
НоваяЗадача = РаботаСЗадачамиHTTP.НоваяЗадачаСотрудника(Запрос, КодОшибки, Заголовки, Код);

 

Функция НоваяЗадачаСотрудника(Запрос, КодОшибки, ЗаголовкиРезультат, КодРезультат) Экспорт
    
    УстановитьПривилегированныйРежим(Истина);
    
    ТипКонтента = ЗначениеПоКлючуВЗаголовках(Запрос.Заголовки, "Content-Type");
    ТелоЗапроса = Запрос.ПолучитьТелоКакСтроку();
    ВходящиеСвойстваЗадачи = Неопределено;
    
    Попытка
    
        Если СтрНачинаетсяС(НРег(ТипКонтента), "application/json") Тогда
            
            ВходящиеСвойстваЗадачи = ПрочитатьЗначениеJSON(ТелоЗапроса);
            
        ИначеЕсли СтрНачинаетсяС(НРег(ТипКонтента), "application/x-www-form-urlencoded") Тогда
            
            ВходящиеСвойстваЗадачи = ЗадачаПоляUrlEncoded(ТелоЗапроса);
        Иначе
            
            КодОшибки = "ТипТела";
            Возврат Неопределено;
        КонецЕсли;
    Исключение
        
        КодОшибки = "ФорматТела";
        Возврат Неопределено;
    КонецПопытки;
    
    Если ТипЗнч(ВходящиеСвойстваЗадачи) <> Тип("Структура") Тогда
        
        КодОшибки = "ФорматТела";
        Возврат Неопределено;
    КонецЕсли;
    
    СвойстваЗадачи = НовыеСвойстваЗадачи();
    ЗаполнитьЗначенияСвойств(СвойстваЗадачи, ВходящиеСвойстваЗадачи);
    
    Отказ = Ложь;
    ПараметрыЗаполнения = РаботаСЗадачамиРеализация.ЗадачаСотрудникаПараметрыЗаполнения();
    
    ПараметрыЗаполнения.Приоритет = ПриоритетЗадачиПоИндентификатору(СвойстваЗадачи.Priority, Отказ);
    ПараметрыЗаполнения.Содержание = СвойстваЗадачи.Text;
    ПараметрыЗаполнения.Исполнитель = ПользовательПоИдентификатору(СвойстваЗадачи.UserID, Отказ);
    ПараметрыЗаполнения.Автор = ПользовательПоИдентификатору(СвойстваЗадачи.AuthorID, Отказ);
    
    РаботаСЗадачамиРеализация.СоздатьЗадачуСотрудника(ПараметрыЗаполнения, СвойстваЗадачи.TaskID, Отказ);
    
    // в теле запроса, может быть указан url для возврата ответа ошибки
    НастроитьПеренаправление(ВходящиеСвойстваЗадачи, "error_url", ЗаголовкиРезультат, КодРезультат);
    
    Если Отказ Тогда
        
        КодОшибки = "ВалидацияДанных";
        Возврат Неопределено;
    КонецЕсли;
    
    Если СвойстваЗадачи.TaskID = Неопределено Тогда
        
        КодОшибки = "ЗадачаНеСоздана";
        Возврат Неопределено;
    КонецЕсли;
    
    // в теле запроса, может быть указан url для возврата ответа
    НастроитьПеренаправление(ВходящиеСвойстваЗадачи, "success_url", ЗаголовкиРезультат, КодРезультат);
    
    Возврат СвойстваЗадачи;
КонецФункции

 

На этом все)

 

 

Критикуйте, делитесь своим опытом в комментариях. Полезно - жмите плюс.

Всем успехов в проектировании http-сервисов!

Вступайте в нашу телеграмм-группу Инфостарт

HTTP-сервис Архитектура Слои Контроллер

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

WEB-интеграция Программист 1С:Предприятие 8 1С:Бухгалтерия 3.0 Бытовые услуги, сервис Платные (руб)

Расширение для автоматизации передачи данных между сервисом Vetmanager с 1С: Бухгалтерия 3.0. Решение позволяет загружать документы и справочники из Ветменеджер в 1С:Бухгалтерию, сокращая время на ручной ввод данных и минимизируя ошибки.

24000 руб.

02.02.2021    23500    73    52    

44

WEB-интеграция Программист Бизнес-аналитик 1С:Предприятие 8 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Оптовая торговля, дистрибуция, логистика ИТ-компания Платные (руб)

Модуль "Экспортер" — это расширение для 1С, предназначенное для автоматизации процессов выгрузки данных. Оно позволяет эффективно извлекать, преобразовывать и передавать данные из систем 1С в интеграционную платформу Spot2D. Подсистема упрощает настройку, снижает количество ручных операций и обеспечивает удобный контроль данных.

17568 руб.

20.12.2024    6773    28    4    

30

Сайты и интернет-магазины WEB-интеграция Системный администратор Программист Пользователь 1С:Предприятие 8 1C:Бухгалтерия 1С:Управление торговлей 11 Автомобили, автосервисы Россия Управленческий учет Платные (руб)

Интеграционный модуль обмена между конфигурацией Альфа Авто 5 и Альфа Авто 6 и порталом AUTOCRM / LOGICSTARS. Данный модуль универсален. Позволяет работать с несколькими обменами AUTOCRM / LOGICSTAR разных брендов в одной информационной базе в ручном и автоматическом режиме.

42700 руб.

03.08.2020    24803    38    26    

29

WEB-интеграция 1С 8.3 1C:Бухгалтерия Автомобили, автосервисы Беларусь Украина Россия Казахстан Управленческий учет Платные (руб)

Расширение для 1С:Управление Автотранспортом (ПРОФ) автоматизирует мониторинг транспорта (пробег, расход, координаты, стоянки) и формирование путевых листов. Включает отчеты, фоновую загрузку данных, работает без активации константы мониторинга. Формы — с открытым кодом, общие модули защищены. Доступна демо-версия. Снижает ручной ввод и повышает точность учета.

23034 руб.

25.05.2021    16235    44    8    

19
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. 9899100 10 15.07.26 21:39 Сейчас в теме
2026 год на дворе, а в 1С все еще разбирают ООП и работу в шаблоне MVC, выражаясь по-русски, пытаются натянуть сову на глобус ...., грустно всё это.
Для отправки сообщения требуется регистрация/авторизация