Перейти к основному содержимому

Добавление новой функциональности

Предположим, нам нужно расширить API, добавив возможность работы с активными пользователями.

Наш модуль будет возвращать список активных пользователей, а также сможет завершать сеансы пользователей.

Для этого нам необходимо.

  1. Скопировать модуль РатШаблонМодуля и переименовать его в РатАктивныеПользователи
  2. Добавить новый модуль в подсистему РатРасширениеФункционала, теперь система будет его учитывать при обработке запросов
  3. Наполнить модуль полезной нагрузкой

Подробнее остановимся на пункте 3. Для начала советую ознакомиться со структурой модуля.

Описание API​

Итак, нам необходимо добавить описание новой функциональности, для этого переходим к методу ЗарегистрироватьОписание. Метод принимает параметр КорневойОбъект, это и есть описание api расширения, в каждом модуле он наполняется данными и сериализуется в json.

В первую очередь нужно определиться со списком операций. Для примера это будут:

  • Получение списка активных сеансов, метод не принимает параметры и возвращает массив структур с описанием сеансов
  • Завершение указанного сеанса, принимает на вход идентификатор сеанса и возвращает признак успешности.

Таким образом, нам нужно описать две операции (список и завершение), их параметры и возвращаемые результаты (массив сеансов и признак успешности).

Следуя правилам именования получаем следующие шаблоны запросов для операций.

  • [GET] /АктивныеПользователи - для получения списка активных пользователей
  • [DELETE] /АктивныеПользователи/{НомерСеанса} - для завершения сеанса пользователя

Описание данных.

  • activeUser - описание активного сеанса
  • activeUser[] - описание результата метода получения списка
  • результатом метода удаления будет предопределенное описание ответа с именем success.

Пример наполнения метода:

    Методы = РатОбщий.МетодыHTTP();
    Путь = "/АктивныеПользователи";
    Описание = "Активные пользователи";
    РатСпецификация.ДобавитьГруппу(КорневойОбъект, Описание, Описание);
    
    ТипСтрока = Тип("Строка");
    ТипЧисло = Тип("Число");
    ТипДата = Тип("Дата");
    
    // Описание элемента "Активный пользователь"
    ИмяТипа = "activeUser";
    ОписаниеПользователя = РатСпецификация.ОписаниеРеквизитов();
    РатСпецификация.ДобавитьОписаниеРеквизита(ОписаниеПользователя, "Имя", "Имя пользователя", ТипСтрока, Истина);
    РатСпецификация.ДобавитьОписаниеРеквизита(ОписаниеПользователя, "НомерСеанса", "Номер сеанса", ТипЧисло, Истина);
    РатСпецификация.ДобавитьОписаниеРеквизита(ОписаниеПользователя, "ТипКлиента", "Клиент", ТипСтрока, Истина);
    РатСпецификация.ДобавитьОписаниеРеквизита(ОписаниеПользователя, "Начало", "Время подключения", ТипДата, Истина);
    
    РатСпецификация.ЗарегистрироватьОписаниеОбъекта(КорневойОбъект, ОписаниеПользователя, ИмяТипа,
        "Описание активного пользователя");
    СсылкаНаОписаниеПользователя = РатOpenAPI.СсылкаНаСхему(ИмяТипа);
    
    // Описание операции получения списка
    Операция = РатOpenAPI.НоваяОперация();
    Операция.summary = "Список активных пользователей";
    Операция.description = "Возвращает список активных пользователей системы";
    Операция.tags.Добавить(Описание);
    
    СхемаОтвета = РатOpenAPI.НоваяСхемаКоллекции(СсылкаНаОписаниеПользователя, "Список активных пользователей");
    РатСпецификация.ДобавитьСтандартныеОтветы(Операция, СхемаОтвета);
    
    РатСпецификация.ЗарегистрироватьОперацию(КорневойОбъект, Путь, Методы.GET, Операция);
    
    // Описание операции отключения пользователя по номеру сеанса
    Операция = РатOpenAPI.НоваяОперация();
    Операция.summary = "Отключение пользователя";
    Операция.description = "Отключает пользователя по номеру сеанса";
    Операция.tags.Добавить(Описание);
    
    РатСпецификация.ДобавитьСтандартныеОтветы(Операция, "success");
    
    РатСпецификация.ДобавитьПараметрОперации(Операция, "НомерСеанса", 
        РатOpenAPI.НоваяСхемаДанных(РатOpenAPI.ТипыДанных().ЦелоеЧисло), "Номер сеанса пользователя");
    
    РатСпецификация.ЗарегистрироватьОперацию(КорневойОбъект, Путь + "/{НомерСеанса}", Методы.DELETE, Операция);

Шаблоны запросов​

Тут все намного проще: шаблоны адресов из прошлого пункта нужно зарегистрировать в системе.

Процедура ЗарегистрироватьШаблоны(ШаблоныСервиса) Экспорт

    Методы = РатОбщий.МетодыHTTP();

    РатШаблоныАдресов.ДобавитьШаблон(ШаблоныСервиса, Методы.GET, "/АктивныеПользователи", "СписокАктивныхПользователей");
    РатШаблоныАдресов.ДобавитьШаблон(ШаблоныСервиса, Методы.DELETE, "/АктивныеПользователи/{НомерСеанса}", "ЗавершениеСеанса");
КонецПроцедуры

Здесь мы указываем коллекцию шаблонов, http-метод, шаблон адреса и идентификатор обработчика. Правильнее вынести идентификаторы в отдельную сущность. Для этого создадим метод.

Функция Обработчики()

    Обработчики = Новый Структура;

    Обработчики.Вставить("СписокАктивныхПользователей", "СписокАктивныхПользователей");
    Обработчики.Вставить("ЗавершениеСеанса", "ЗавершениеСеанса");

    Возврат Новый ФиксированнаяСтруктура(Обработчики);

КонецФункции

И скорректируем метод ЗарегистрироватьШаблоны.

Процедура ЗарегистрироватьШаблоны(ШаблоныСервиса) Экспорт

    Методы = РатОбщий.МетодыHTTP();
    Обработчики = Обработчики();

    РатШаблоныАдресов.ДобавитьШаблон(ШаблоныСервиса, Методы.GET, "/АктивныеПользователи", Обработчики.СписокАктивныхПользователей);
    РатШаблоныАдресов.ДобавитьШаблон(ШаблоныСервиса, Методы.DELETE, "/АктивныеПользователи/{НомерСеанса}", Обработчики.ЗавершениеСеанса);
КонецПроцедуры

Вызов обработчиков​

Описания готовы, теперь нужно реализовать логику сервиса.

Реализуем метод получения списка активных пользователей, для этого создадим метод с именем по шаблону Обработчик[Идентификатор обработчика].

Функция ОбработчикСписокАктивныхПользователей(ПараметрыЗапроса, СтатусОбработкиЗапроса)

Метод принимает данные запроса, а также служебный объект для регистрации ошибок и возвращает ответ сервиса - сериализуемый объект.

Список активных сеансов мы можем получить из метода платформы ПолучитьСеансыИнформационнойБазы, но тип СеансИнформационнойБазы не сериализуется, и нам нужно переложить данные в массив структур. В итоге получаем такой метод.

Функция ОбработчикСписокАктивныхПользователей(ПараметрыЗапроса, СтатусОбработкиЗапроса)

    Результат = Новый Массив();

    Для Каждого Сеанс Из ПолучитьСеансыИнформационнойБазы() Цикл
        ОписаниеСеанса = Новый Структура();
        ОписаниеСеанса.Вставить("НомерСеанса", Сеанс.НомерСеанса);
        ОписаниеСеанса.Вставить("ИмяКомпьютера", Сеанс.ИмяКомпьютера);
        ОписаниеСеанса.Вставить("ИмяПриложения", Сеанс.ИмяПриложения);
        ОписаниеСеанса.Вставить("Пользователь", Сеанс.Пользователь.Имя);
        Результат.Добавить(ОписаниеСеанса);
    КонецЦикла;

    Возврат Результат;

КонецФункции

И для того, чтобы метод стал доступен системе, нужно добавить его вызов в метод ВызватьОбработчик, получим следующее.

Функция ВызватьОбработчик(Обработчик, ПараметрыЗапроса, СтатусОбработкиЗапроса, ОбработчикВыполнен) Экспорт

    Обработчики = Обработчики();
    Результат = Неопределено;

    Если Обработчик = Обработчики.СписокАктивныхПользователей Тогда
        
        Результат = ОбработчикСписокАктивныхПользователей(ПараметрыЗапроса, СтатусОбработкиЗапроса);
        ОбработчикВыполнен = Истина;
        
    КонецЕсли;

    Возврат Результат;

КонецФункции