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

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

Предположим, нам нужно расширить 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, "/АктивныеПользователи/{НомерСеанса}", Обработчики.ЗавершениеСеанса);
КонецПроцедуры

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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