Маршрутизация запросов #
Документация #
- Официальная документация на библиотеку http4k
- Простая маршрутизация с http4k
- Переменные в пути маршрутизатора
Задачи #
Продолжайте разработку приложения, которую начали на прошлом занятии. В рамках текущего занятия необходимо добавить отображение страниц с детальной информацией о конкретном треугольнике. Сначала задачу необходимо реализовать с помощью метода маршрутизации, предоставляемом библиотекой http4, а затем реализовать свою собственную функцию по маршрутизации.
На каждой странице сайта должна показываться навигационная панель, в которой есть ссылка на страницу со списком треугольников.
Ниже представлены шаги по решению данной задачи.
Отображение информации о треугольнике #
Реализуйте отображение информации о треугольнике на отдельной странице. На данной странице необходимо выводить всю информацию о конкретном треугольнике. Маршрут для отображения элемента списка /triangle/{number}, где number — это порядковый номер в списке треугольников. На странице также необходимо отображать ссылку для перехода к списку треугольников.
- Создайте компонент для формирования HTML-документа, описывающего данные для конкретного треугольника,
ru.yarsu.web.view.TriangleView. В качестве входных данных компонент должен принимать ссылку на объект треугольника,Triangle. В качестве выхода он должен формировать HTML-документ с описанием треугольника. - Создайте класс HTTP-обработчика для отображения детальной информации о треугольнике.
- Создайте класс
ru.yarsu.web.handlers.ShowTriangleHandler. - Конструктор класса должен принимать ссылку на объект класса
Triangles. - Реализуйте функцию
invoke, логику по обработке HTTP-запроса. Внутри данной функции:- Получите порядковый номер треугольника из переменной пути
number. Для извлечения значения данной переменной из пути используйте функциюRequest.path. - Преобразуйте полученную строку к числу с использованием функции
toIntOrNull(). На настоящий момент будем подразумевать, что передаваемые данные корректны. - Получите ссылку на указанный треугольник из списка треугольников,
Triangles. С помощью функцииfetchTriangleByNumber(number: Int). - Сформируйте HTML-документ с помощью компонента
TriangleView. - Сформируйте HTTP-ответ, содержащий статус
OKи HTML-документ в теле ответа.
- Получите порядковый номер треугольника из переменной пути
- Создайте класс
- Свяжите созданный HTTP-обработчик с маршрутом
/triangle/{number}внутри функции по формированию маршрутизатора,router. Передайте функции по созданию обработчику ссылку на объектTriangles.
Обработка ошибочного параметра #
Доработайте обработчик маршрута /triangle/{number} таким образом, чтобы приложение вело себя корректно в следующих ситуациях:
- Переданный аргумент не содержит целого числа.
- Передан некорректный номер треугольника в списке.
В данных случаях приложение должно сообщать пользователю о неправильных параметрах.
Создание собственного маршрутизатора #
Подсистема для связывания путей с обработчиками маршрутов в http4k очень гибкая:
- Позволяет связывать обычные обработчики маршрута с путями.
- Позволяет связывать маршрутизируемые обработчики с путями.
- Позволяет объединять маршрутизируемые обработчики вместе.
С её помощью можно реализовать практически любой подход к описанию логики маршрутизации в системе. Настоятельно рекомендуется использовать именно родную подсистему для выполнения маршрутизации внутри приложения.
В рамках данной части занятия предлагается задача по созданию собственной, гораздо более простой, версии функции-маршрутизатора. Будем работать в следующих ограничениях:
- Разрабатываем функцию специально для данного приложения. Не надо пытаться решить общую задачу, как это сделано в наборе функций от библиотеки http4k.
- Обработчики HTTP-запросов не должны знать об изменениях в маршрутизаторе.
Как работает функция Request.path
#
Ввиду последнего ограничения необходимо обеспечить работу обработчика HTTP-запроса ru.yarsu.ShowTriangleHandler. Данный обработчик извлекает данные с помощью метода Request.path. Рассмотрим его реализацию:
fun Request.path(name: String): String? = when (this) {
is RequestWithRoute -> xUriTemplate.extract(uri.path)[name]
else -> throw IllegalStateException("Request was not routed, so no uri-template present")
}Из реализации видно, что функция работает не с интерфейсом Request, а с интерфейсом RequestWithRoute. Единственный класс, который реализует данный интерфейс внутри библиотеки http4k — это
RoutedRequest(private val delegate: Request, override val xUriTemplate: UriTemplate)
: Request by delegate, RequestWithRouteRoutedRequest, соединяющие в себе оригинальный объект запроса и шаблон шаблон стандартной подсистемы маршрутизации.
Работа с путём запроса #
Внутри объектов Request содержится поле uri, которое содержит внутри себя объект Uri, описывающий URI-путь внутри запроса. Путь запроса содержится внутри поля path данного объекта.
Путь — это строка, класс String, которую можно обрабатывать с помощью любых функций для строк, например:
- split для разделения строк на части,
- startsWith для проверки префикса строки.
Реализация функции-маршрутизатора #
- Создайте новый HTTP-обработчик,
ru.yarsu.web.handlers.AppRouter. - Конструктор класса должен принимать ссылки на другие HTTP-обработчики.
- Внутри функции по обработке HTTP-запроса выполните следующие действия:
- Сравните весь путь со строкой
"/". Если он совпал, то передайте обработку запроса объекту класса"ru.yarsu.web.handlers.RedirectToTriangleListHandler". - Сравните весь путь со строкой
"/ping". Если он совпал, то передайте обработку запроса объекту классаru.yarsu.web.handlers.PongHandler. - Сравните весь путь со строкой
"/triangles". Если он совпал, то передайте обработку запроса объекту класса"ru.yarsu.web.handlers.ListTrianglesHandler". - Проверьте, что путь начинается со строки
"/triangles/". Если условие выполнилось, то передайте обработку запроса объектуru.yarsu.ShowTriangleHandler. Перед передачей запроса в обработчик оберните объект запроса оберните классRoutedRequest. В качестве шаблона пути используйте/triangles/{number} - Если ни одна из проверок не была выполнена, то верните ответ с кодом 404, NOT_FOUND.
- Сравните весь путь со строкой
- Используйте объект класса
ru.yarsu.web.handlers.AppRouterв качестве основного обработчика HTTP-запросов внутри приложения. Удостоверьтесь, что все HTTP-запросы корректно обрабатываются приложением, пользователю доступны все ссылки.