В этом примере, чтобы получить актуальные цены товаров на заданную дату, нам понадобится получить срез последних записей на эту дату из регистра сведений ЦеныТоваров и подставить список товаров их цен в тело ответа, возвращаемого сервисом.
Итак, добавим у нашего HTTP-сервиса объект Шаблон URL ПолучитьЦены с шаблоном /date/{Дата}. Затем у этого объекта добавим подчиненный метод GET, в качестве HTTP-метода оставим предложенное по умолчанию значение GET. Далее создадим обработчик этого метода.
В модуле нашего HTTP-сервиса будет создан шаблон функции-обработчика ПолучитьЦеныGET(). Заполним эту функцию следующим образом (листинг 1.67).
Листинг 1.67. Функция «ПолучитьЦеныGET»
Функция ПолучитьЦеныGET(Запрос)
Попытка
// Получить из запроса параметр URL Дата.
ДатаЗапроса = Запрос.ПараметрыURL.Получить("Дата");
Если ДатаЗапроса = Неопределено Тогда
Ответ = Новый HTTPСервисОтвет(400);
Ответ.УстановитьТелоИзСтроки("Не задан параметр Дата");
Ответ.Заголовки.Вставить("Content-type", "application/json");
Возврат Ответ;
КонецЕсли;
ЦеныНаДату = Дата(ДатаЗапроса);
// Сформировать запрос к регистру сведений.
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ЦеныТоваровСрезПоследних.Период КАК Период,
| ЦеныТоваровСрезПоследних.Товар КАК Товар,
| ЦеныТоваровСрезПоследних.Цена КАК Цена
|ИЗ
| РегистрСведений.ЦеныТоваров.СрезПоследних(&ЦеныНаДату, ) КАК ЦеныТоваровСрезПоследних";
Запрос.УстановитьПараметр("ЦеныНаДату", ЦеныНаДату);
Выборка = Запрос.Выполнить().Выбрать();
// В цикле обхода выборки записать в JSON последние цены товаров
// Создать объект записи и записать строковое значение в строку JSON.
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
// Записать начало корневого объекта.
Запись.ЗаписатьНачалоОбъекта();
Пока Выборка.Следующий() Цикл
Запись.ЗаписатьИмяСвойства(Строка(Выборка.Товар));
Запись.ЗаписатьНачалоОбъекта();
Запись.ЗаписатьИмяСвойства("Период");
Запись.ЗаписатьЗначение(Строка(Выборка.Период));
Запись.ЗаписатьИмяСвойства("Цена");
Запись.ЗаписатьЗначение(Выборка.Цена);
Запись.ЗаписатьКонецОбъекта();
КонецЦикла;
// Записать конец корневого объекта.
Запись.ЗаписатьКонецОбъекта();
// Записать результат записи в строку JSON.
Результат = Запись.Закрыть();
// Сформировать ответ, возвращаемый HTTP-сервисом.
Ответ = Новый HTTPСервисОтвет(200);
// Установить тело ответа из строки Результат.
Ответ.УстановитьТелоИзСтроки(Результат);
Исключение
// Вывести стуктурированную информацию об исключении.
Ответ = Новый HTTPСервисОтвет(500);
Информация = ИнформацияОбОшибке();
Сообщение = Информация.Описание;
Если Информация.Причина <> Неопределено Тогда
Сообщение = Сообщение + ":" + Информация.Причина.Описание;
КонецЕсли;
Ответ.УстановитьТелоИзСтроки(Сообщение);
КонецПопытки;
Ответ.Заголовки.Вставить("Content-type", "application/json");
Возврат Ответ;
КонецФункции
Прокомментируем код функции.
Родительский объект функции-обработчика – шаблон URL ПолучитьЦены, описанный с помощью шаблона /date/{Дата}. Этот шаблон содержит непараметризованный сегмент date и параметризованный сегмент {Дата}. Это означает, что любые символы, которые могут присутствовать в URL запроса к сервису после символов «/date/», будут трактоваться как параметр URL Дата, который можно получить из переданного в функцию параметра Запрос.
Поэтому сначала в обработчике мы делаем попытку получить значение параметра Дата (Запрос.ПараметрыURL.Получить("Дата")) и анализируем его. Если этот параметр URL не определен, то мы прекращаем работу функции и возвращаем ответ сервиса с кодом состояния 400, сообщающим об ошибке запроса.
Затем мы преобразуем строковое значение параметра Дата в дату ЦеныНаДату, которую подставляем в качестве параметра в запрос, обращающийся к срезу последних регистра ЦеныТоваров.
В цикле обхода выборки мы заполняем строку JSON списком последних цен товаров на дату, переданную в параметре запроса, и затем записываем эту строку в переменную Результат. После этого создаем объект HTTPСервисОтвет с кодом состояния 200, с помощью метода УстановитьТелоИзСтроки() устанавливаем тело ответа HTTP-сервиса из строки Результат и возвращаем ответ сервиса в переменной Ответ.
При этом заголовок «Content-type» объекта HTTPСервисОтвет мы устанавливаем как «application/json». Такой заголовок помогает клиенту понять, что же за данные к нему пришли, кроме того, из него определяется кодировка ответа, если она не задана явно.
Если же при попытке получить значение параметра URL из запроса возникает ошибка, то генерируется исключение. С помощью метода глобального контекста ИнформацияОбОшибке() мы получаем структурированную информацию об исключении и возвращаем ответ сервиса с кодом состояния 500, сообщающим о причине ошибки.
Теперь посмотрим, как это работает.
Прежде всего опубликуем наш HTTP-сервис на веб-сервере. О том, как это делается, уже рассказывалось в примере про HTTP-сервис Сотрудники (см. рис. 1.14).
После этого наберем в адресной строке браузера следующий URL (листинг 1.68).
Листинг 1.68. URL запроса
http://localhost/REST/hs/prices/date/20190510
В URL запроса к HTTP-сервису после символов «/date/» присутствует строковое представление даты – 10/05/2019. Поэтому такой URL будет сопоставлен с шаблоном URL ПолучитьЦены (строка шаблона – /date/{Дата}) и будет вызван обработчик этого шаблона ПолучитьЦеныGET(). В результате в окне браузера мы увидим содержимое ответа сервиса (листинг 1.69).
Листинг 1.69. Содержимое ответа сервиса
{
"Чайник": {
"Период": "07.05.2019 0:00:00",
"Цена": 3000
},
"Тостер": {
"Период": "07.05.2019 0:00:00",
"Цена": 2000
},
"Кофемашина": {
"Период": "07.05.2019 0:00:00",
"Цена": 5000
}
}