Написание простых приложений на http4k #
Документация #
- Официальная документация на библиотеку http4k
- Простая маршрутизация с http4k
- Обработчики HTTP-запросов
- Раздача статических данных
- Использование шаблонизаторов
Шаблон приложения #
Скачайте архив, с исходным кодом проекта по ссылке. Данный проект основан на базовом шаблоне проекта, в который были внесены изменения.
Стартовой функцией приложения является функция main
, расположенная в файле ru/yarsu/WebApplication.kt
. Эта информация внесена в конфигурационный файл системы сборки Gradle.
В пакете ru.yarsu.web
расположен код приложения, выполняющий обработку HTTP-запросов.
Маршрутизатор HTTP-запросов приложения описывается в файле ru/yarsu/web/Router.kt
и записывается в переменную router
.
Классы, реализующие HTTP-обработчики, помещены в пакет ru.yarsu.web.handlers
. Для каждого из двух обработчиков создан отдельный класс в отдельном файле.
В стартовой функции main
динамические маршруты приложения объединяются с обработчиком HTTP-запросов за статическими (неизменяемыми) данными. Статические данные берутся из ресурсов приложения по пути ресурсов /ru/yarsu/public
. На момент компиляции приложения они расположены в каталоге проекта src/main/resources/ru/yarsu/public
.
В каталоге со статическими данными добавлены CSS и JS-файлы библиотеки Bootstrap. Ввиду конфигурации подсистемы раздачи статических файлов они будут доступны по частичному абсолютному пути /css/bootstrap.min.css
и /js/bootstrap.bundle.min.js
.
Использование шаблонов Pebble #
В рамках библиотеки http4k предоставляется унифицированная прослойка для работы с разными шаблонизаторами. В рамках данной прослойки выделены два элемента — компонент для настройки параметров шаблонизатора и классы-модели.
Настройка шаблонизатора #
Первые компоненты позволяют получить доступ к шаблонизатору и настроить политику кеширования. В рамках обработчика ru.yarsu.web.handlers.PebbleHandler
данный объект создаётся следующим образом:
val renderer = PebbleTemplates().CachingClasspath()
Берётся конфигурация шаблонизатора Pebble по умолчанию, а затем выбирается стратегия по получению Pebble шаблонов из ресурсов приложения с выполнением кеширования. Помимо неё доступны ещё следующие стратегии:
- Кеширование шаблонов из файловой системы,
Caching()
. - Прямая загрузка шаблонов из файловой системы без кеширования,
HotReload()
.
Последняя политика полезна при разработке, т.к. позволяет просматривать результаты применения шаблона без перезапуска приложения.
Использование моделей #
Вторым компонентом системы являются модели. Модели — это классы, реализующие интерфейс org.http4k.template.ViewModel
. Данный интерфейс не накладывает никакие ограничения на класс, но предоставляет функцию template()
, которая по каноническому названию класса формирует путь к шаблону, который будет использован при её отображении.
В примере создана модель ru.yarsu.web.models.PebbleVM
. Для данной модели путём для соответствующего ей шаблона является /ru/yarsu/web/models/PebbleVM.peb
. Данный путь будет разрешён согласно конфигурации объекта-шаблонизатора.
При вызове шаблонизатора renderer(viewModel)
будет вычислен путь к шаблону и ему в качестве данных будет передан объект модели. Модель будет доступна внутри шаблона по названию model
.
Пути к другим моделям #
При использовании техники наследования шаблонов или при включении шаблонов необходимо использовать относительные пути с указанием текущего каталога. Например для подключения файла-раскладки Layout.peb
, находящегося рядом с текущим файлом, с помощью тега extends
необходимо использовать путь ./Layout.peb
, а не Layout.peb
.
Задача № 1. Создание обработчика корневого маршрута #
Реализуйте в приложении обработчик корневого маршрута /
. При обращении к корневому маршруту должна динамически формироваться HTML-страница с изображениями всех видов треугольников: остроугольный, тупоугольный, прямоугольный, разносторонний, равнобедренный и равносторонний.
Ниже представлен подход к решению задачи.
- Сформируйте набор изображений треугольников в каталоге
src/main/resources/ru/yarsu/public/images
. Изображения можно сформировать самостоятельно или взять с ресурсов сети интернет. В последнем случае учитывайте условия использования чужого изображения. Данные изображения будут доступны по частичному абсолютному пути/images/isosceles.png
. - Создайте обработчик HTTP-запроса, который будет на текущий момент отвечать пустой строкой.
- Создайте класс
ru.yarsu.web.handlers.HomeHandler
. - Унаследуйте данный класс от функционального типа
org.http4k.core.HttpHandler
. - Внутри реализуемой функции
ivoke
создайте ответ с кодом статуса OK, содержащий строкуСтартовая страница
.
- Создайте класс
- Свяжите созданный обработчик с маршрутом
/
.- Внутри маршрутизатора добавьте связь маршрута
/
с объектом созданного на предыдущем шаге классаHomeHandler
. - Перезапустите приложение и обратитесь к нему по корневому пути. Убедитесь, что в браузере отображается слово
Стартовая страница
.
- Внутри маршрутизатора добавьте связь маршрута
- Реализуйте Pebble-шаблон HTML-документа с необходимым содержимым. Разместите содержимое в файле
src/main/resources/ru/yarsu/web/models/HomePageVM.peb
.- В качестве базы для реализации возьмите содержимое файла
PebbleVM.peb
. - Добавьте необходимое текстовое и мультимедиа содержимое внутри данного файла.
- В качестве базы для реализации возьмите содержимое файла
- Создайте модель для связи шаблонизатора и данного файла.
- Создайте пустой класс
ru.yarsu.web.models.HomePageVM
. - Унаследуйте данный класс от интерфейса
org.http4k.template.ViewModel
.
- Создайте пустой класс
- Внутри HTTP-обработчика стартовой страницы используйте шаблонизатор, класс-модель и шаблон для отображения содержимого страницы.
- Внутри класса
ru.yarsu.web.handlers.HomeHandler
создайте Pebble-шаблонизатор средствами библиотеки http4k. Выберите режим кеширующей работы с данными из ресурсов. - Создайте строку на основании шаблона. Примените шаблонизатор к объекту класса
ru.yarsu.web.models.HomePageVM
. - Выведите созданную строку с текстом HTML-документа в качестве ответа на запрос вместо строки
Стартовая страница
. - Перезапустите приложение и обратитесь к нему по корневому пути. Убедитесь, что в браузере корректно отображается нужная страница.
- Внутри класса
Задача № 2. Создание одного объекта-шаблонизатора Pebble #
При создании обработчика HTTP-запроса был создан объект для настройки шаблонизатора внутри его. Вроде бы написали всего одну строчку, но в каждом следующем обработчике придётся дописывать данную строчку. Другая проблема — если в будущем потребуется внести настройки в шаблонизатор, то придётся вносить это изменение во все обработчики.
Логичным решением является уменьшение дублирования логики между HTTP-обработчиком путём передачи созданного объекта в качестве параметра конструктора обработчика. В результате объём кода HTTP-обработчиков уменьшится, появится возможность выполнения настройки в едином месте.
Решите проблему дублирования при создании объекта-шаблонизатора. Данный объект должен создаваться в стартовой функции и затем передаваться через маршрутизатор в конкретные обработчики HTTP-запросов.
Ниже представлен подход к решению задачи.
- Создайте функцию по формированию объекта-шаблонизатора.
- Создайте файл
ru/yarsu/web/TemplateRenderer.kt
. - Создайте в файле функцию, которая возвращает объект типа
org.http4k.template.TemplateRenderer
. Данная функция должна принимать в качестве аргумента логический тип. - В зависимости от значения переданного аргумента функция должна возвратить либо кеширующий шаблонизатор, либо шаблонизатор с прямой загрузкой данных с жёсткого диска.
- Создайте файл
- Вызовите данную функцию в стартовом файле приложения, результат вызова функции поместите в переменную. При разработке приложения можете использовать вариант шаблонизатора, загружающий данные с жёсткого диска.
- Замените переменную для хранения маршрутизатора функцией, которая принимает в качестве аргумента объект шаблонизатора и возвращающей объект типа
org.http4k.routing.RoutingHttpHandler
.- В файле
ru/yarsu/web/Router.kt
замените переменнуюrouter
на функциюrouter
. - Добавьте данной функции необходимый аргумент — ссылку на объект шаблонизатора.
- Убедитесь, что функция возвращает созданный маршрутизируемый обработчик HTTP-запросов.
- Вызовите данную функцию в старотовом файле приложения вместо обращения к переменной, передайте ей в качестве аргумента ссылку на созданный на предыдущем шаге объект шаблонизатора.
- В файле
- Передайте объект шаблонизатор во все обработчики HTTP-запросов и замените им создание собственных обработчиков. Для каждого HTTP-обработчика:
- Добавьте в конструктор передачу ссылки на объект шаблонизатора. Данную ссылку необходимо сохранить в приватном неизменяемом поле класса. Объект необходим только внутри обработчика, поэтому поле не должно быть доступно вне объектов класса.
- Удалите создание новых объектов в существующих HTTP-обработчиках.
- Перезапустите приложение и убедитесь, что приложение функционирует корректно.
Задача № 3. Реализация навигационной панели и общей раскладки #
В созданных Pebble-шаблонах также присутствует дублирование:
- В логике подключения ресурсов.
- В базовой раскладке. Она только усилится при добавлении навигационной панели.
В рамках данного шага вынесите общую логику в отдельный файл-раскладку и измените существующие Pebble-шаблоны на её использование.
- Создайте файл-раскладку
src/main/resources/web/models/partials/Layout.peb
.- Перенесите в данный файл общее содержимое.
- Определите блоки для расширения: заголовок страницы и содержимое страницы.
- Измените каждый из существующих Pebble-шаблонов на использование данной раскладки.
- Корректно укажите путь для расширения файла-раскладки. Относительный путь будет выглядеть как
./partials/Layout.peb
. - Заполните блоки расширения соответствующей информацией.
- Корректно укажите путь для расширения файла-раскладки. Относительный путь будет выглядеть как
- Перезапустите приложение и удостоверьтесь, что приложение успешно отображает обе страницы, использующие Pebble-шаблоны.
- Добавьте навигационную панель, позволяющую переходить между всеми разделами сайта.
- В файл-раскладке разместите навигационную панель, включающую ссылку к корневому маршруту и к маршруту по отображению страницы-демонстратора работы с Pebble-шаблонами.
- Перезапустите приложение и удостоверьтесь, что приложение позволяет переходить между данными страницами без ручного редактирования адресной строки в браузере.
Задача № 4. Отображение списка треугольников #
Реализуйте отображение страницы со списком треугольников, информацию о которых располагает веб-приложение. Для каждого треугольника на данной странице необходимо выводить только порядковый номер и его площадь. Можно использовать табличное или списочное представление.
Маршрут для отображения страницы — /triangle/
.
Ниже представлен подход к решению задачи.
- Возьмите код для чтения списка треугольников из предыдущих практик. Расположите класс для описания треугольника в пакете
ru.yarsu.domain
. - В стартовой функции приложения реализуйте считывание списка треугольников из файла.
- Создайте модель для отображения списка треугольников. В классе
ru.yarsu.web.handlers.TrangleListVM
добавьте полеtriangles
для хранения списка треугольников. - Создайте Pebble-шаблон для отображения списка треугольников. Внутри шаблона используйте
model.triangles
для доступа к списку треугольников. - Создайте обработчик HTTP-запроса для отображения списка треугольников.
- Данный обработчик должен принимать в качестве аргументов список треугольников и объект-шаблонизатора.
- На основании переданных данных обработчик должен формировать HTML-документ и возвращать его в качестве тела ответа.
- Свяжите созданный обработчик с путём
/triangle
в маршрутизаторе.- Добавьте функции по созданию маршрутизатора аргумент — список треугольников.
- Внутри функции используйте данный аргумент для создания объекта HTTP-обработчика для класса, описанного в предыдущем шаге.
- Свяжите созданный объект с GET-запросом по пути
/triangle
. - В стартовой функции передайте функции по созданию маршрутизатора объект со списком треугольников.
- Добавьте в общую навигационную панель путь к странице со списком треугольников.
- Перезапустите приложение. Убедитесь, что пользователь со стартовой страницы может перейти на страницу со списком треугольников и назад, к стартовой странице.