Маршрутизация запросов #
Документация #
- Официальная документация на библиотеку 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, RequestWithRoute
RoutedRequest
, соединяющие в себе оригинальный объект запроса и шаблон шаблон стандартной подсистемы маршрутизации.
Работа с путём запроса #
Внутри объектов 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-запросы корректно обрабатываются приложением, пользователю доступны все ссылки.