Обработка переменных пути

Обработка переменных пути #

Описание маршрутизатора и обработчика с переменной пути #

При описании маршрутов в маршрутизаторе http4k разработчик может указать переменную пути:

val triangleStorage = TriangleStorage()
val getTriangleByIdOperation = getTriangleByIdOperationImpl(triangleStorage)
val triangleHandler = TriangleHandler(getTriangleByIdOperation)
routes(
    "/triangles/{id}" bind Method.GET to triangleHandler,
)

Внутри обработчика можно получить доступ к переменной пути с помощью метода Request.path:

class TriangleHandler(
    private val getTriangleByIdOperation: GetTriangleByIdOperation
) : HttpHandler {
    override fun invoke(request: Request): Response {
        val id: String? = request.path("id")
        ...
    }
}
  • Данные приходят в строковом формате.
  • Данные могут не придти от пользователя.

Как работает функция Request.path #

Рассмотрим реализацию функции 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, обладающий следующим конструктором:

RoutedRequest(private val delegate: Request, override val xUriTemplate: UriTemplate)
Таким образом внутрь HTTP-обработчика надо передавать объекты класса RoutedRequest, соединяющие в себе оригинальный объект запроса и шаблон шаблон стандартной подсистемы маршрутизации.

Описание шаблона пути происходит с помощью класса UriTemplate, который можно создать с помощью фукнции-конструктора UriTemplate.from.

Задание № 1. Реализация хранилища треугольников #

Добавьте к треугольнику новое поле — уникальный идентификатор. В качестве типа идентификатора удобно выбрать число: целое число или UUID. Рекомендуется оформить класс треугольника как класс данных с неизменяемыми полями.

Для управления списком уникальных треугольников реализуйте хранилище треугольников. Данный класс должен предоставлять следующие возможности:

  • Хранение списка треугольников.
  • Получение всех треугольников.
  • Добавление треугольника.
  • Получение треугольника по его уникальному идентификатору. Данная функция может вернуть либо объект треугольника, либо null, если не был найден треугольник с данным идентификатором.

Данными этого класса должны стать:

  • Словарь с ключами уникального идентификатора и значением объектами треугольниками.
  • Счётчик уникальных идентификаторов. Поля класса должны быть приватными, т.к. они являются изменяемыми.

Параметрами конструктора должен стать список треугольников. На основании данного списка формируются данные класса.

Задание № 2. Реализация отображения конкретного треугольника #

Реализуйте отображение информации о конкретном треугольнике по пути /triangles/{id}. Если по указанному пути треугольник не был найден, то обработчик должен возвращать статус 404, NOT_FOUND.

Ключевые части по решению задачи:

  • Добавьте операцию по получению треугольника из хранилища.
  • Добавьте Pebble-шаблон для отображения информации о конкретном треугольнике.
  • Реализуйте HTTP-обработчик для отображения информации о треугольнике:
    • Он должен принимать в качестве аргумента объекты шаблонизатора и операции.
    • Из запроса извлеките значение переменной пути id, преобразуйте его к идентификатору.
    • Используйте операцию, передав ей полученный идентификатор.
    • Если на каком-то из этапов данные не удалось получить, верните ответ со статусом 404, NOT_FOUND.
    • При успешном получении треугольника из операции верните ответ со статусом 200 и содержимым HTML-документа, полученным в результате создания шаблона.
  • Реализуйте модульные тесты на созданный HTTP-обработчик.
  • Добавьте ссылки на страницы с информацией о конкретных треугольников со страницы со списком треугольников

Задание № 3. Добавление фильтра по обработке статуса 404 #

При получении запроса к несуществующему документу HTTP-приложение вернёт ответ со статусом 404:

  • Маршрутизатор возвращает данный статус, если обработчик запроса не был найден.
  • Обработчик маршрута для получения списка треугольников возвращает статус, если данные были переданы в неправильном формате или если треугольник с указанным идентификатором не был найден.

В приложении необходимо добавить фильтр HTTP-запросов. Данный фильтр должен работать с динамическими маршрутами приложения. В случае возвращения динамическим маршрутом ответа со статусом 404 фильтр должен сформировать HTML-документ, с помощью которого пользователь может продолжить работу с сайтом.

Ключевые части по решению задачи:

  • Сформируйте Pebble-шаблон для отображения информации в случае ошибки доступа.
    • На странице должна находится навигационная панель.
    • На странице должно быть сообщение о том, что по данному пути документ не может быть найден.
    • На странице должна быть информация о том по какому URL был выполнен запрос.
  • В пакете su.yarsu.web.filters создайте фильтр NotFoundFilter. В конструктор фильтра передайте ссылку на шаблонизатор.
    • При получении ответа от оборачиваемого HTTP-обработчика фильтр должен проверить его статус. Если статус 404, то фильтр должен вернуть страницу с сообщением об ошибке.
  • Примените фильтр к динамическим маршрутам приложения.

© A. M. Васильев, 2024, CC BY-SA 4.0, andrey@crafted.su