Применение линз

Применение линз для проверки данных от пользователя #

Документация #

Особенности работ с линзами #

К сожалению базовый интерфейс линз не позволяет обработать некорректные значения, а также частично заполненные данные. Для решения подобных проблем можно воспользоваться следующими методами-обёртками. Они рассчитаны на использование с линзами, терминатором которых был использован optional() или required().

import org.http4k.lens.Lens
import org.http4k.lens.LensFailure

fun <IN : Any, OUT>lensOrNull(lens: Lens<IN, OUT?>, value: IN): OUT? =
    try {
        lens.invoke(value)
    } catch (_: LensFailure) {
        null
    }

fun <IN : Any, OUT>lensOrDefault(lens: Lens<IN, OUT?>, value: IN, default: OUT): OUT =
    try {
        lens.invoke(value) ?: default
    } catch (_: LensFailure) {
        default
    }

Вариант вызова данных функций-обёрток:

val pathLens = Path.int().of("id")
lensOrNull(pathLens, request)

В качестве альтернативы данным методам можно рассмотреть использование объектов Result из библиотеки Result4k.

Задача № 1. Использование линз для формирования HTML-документов #

В текущей ситуации приложение не оповещает своих клиентов о типе документов, которые возвращаются после обращения к маршрутам. Созданные HTML-документы должны иметь тип text/html.

  1. Создайте линзу на основе ранее созданного шаблонизатора. У линзы укажите тип данных ContentType TEXT_HTML.
  2. Передайте линзу вместо шаблонизатора в маршрутизатор, а из него в соответствующие обработчики маршрута.

Созданная линза будет обладать типом BiDiBodyLens<ViewModel>. Для упрощения кода обработчиков можно ввести псевдоним для данного типа:

typealias htmlRenderer = BiDiBodyLens<ViewModel>

После изменения приложения удостоверьтесь, что при возвращении HTML-документов им корректно устанавливается корректный тип данных в заголовках ответа.

Задача № 2. Обработка переменной пути #

В рамках процесса обработки запроса для отображения конкретного треугольника необходимо обработать номер треугольника, передающийся как переменная пути.

  • Если в рамках переменной передано не-число, то обработчик должен возвращать код ошибки 400, BAD_REQUEST.
  • Если по указанному числу невозможно найти запись о добавленном треугольнике, то обработчик должен возвращать код ошибки 400, BAD_REQUEST.
  • Если удалось найти нужный треугольник, то вывести HTML-документ пользователю.

Подход к реализации с использованием линз.

  1. Создайте линзу для получения параметра пути с помощью Path.
  2. Укажите преобразование пути к целому числу, int().
  3. Укажите данный параметр обязательным, required().
  4. Примените линзу к запросу, полученному от пользователя triangleNumberLens(request).
  5. Добавьте обработку исключения LensFailure. В случае возникновения исключительной ситуации обработчик должен возвращать ответ с кодом 400, BAD_REQUEST.

Можете воспользоваться одной из функций-обёрток.

Задача № 3. Обработка параметров формы добавления новых треугольников #

При работе с формой добавления треугольника форма должна:

  • Не терять данные, которые ввёл пользователь.
  • Показывать сообщения: почему форма не была принята сервером.
  • Принимать корректный ввод от пользователя.

Механизм линз позволяет решить поставленную задачу для обработки данных на техническом уровне при использовании стандартных методов для преобразования. Потенциально можно добавить и логические проверки, если к преобразованию данных добавить собственные шаги.

Для реализации линз к полям формы используйте базовый объект FormField, а линзу для получения данных с формы формируйте с помощью Body.webForm.

Подход к реализации

  1. Опишите линзы для обработки полей формы внутри обработчика HTTP-запроса на добавление треугольника.
    • Для каждой из сторон треугольника создайте линзу на основе FormField.
    • Укажите тип данных для преобразования строки в вещественное число, double().
    • Укажите, что данные поля являются необходимыми для заполнения формы, т.е. используйте терминатор required(). В рамках вызова метода укажите название поля формы и описание.
    • Описание линз следует вынести вне кода функций-обработчика, т.к. их описание не зависит от данных, приходящих от пользователя. Данные линзы будут пытаться преобразовать любой ввод от пользователя к прдустановленному формату.
  2. Опишите линзу для обработки формы.
    • Объедините отдельные линзы для полей формы в единую линзу для всей формы с помощью Body.webForm.
    • В качестве валидатора формы используйте Validator.Feedback. Данный валидатор соберёт все сообщения об ошибках в результирующий объект, а не выбросит исключение при несоответсвии данных запросам линз.
  3. Преобразуйте модель шаблонизатора для отображения формы ввода данных треугольника так, чтобы он принимал объект типа WebForm.
  4. В рамках обработчика запроса на показ формы инициализируйте данную модель с помощью пустого экземпляра класса WebForm. Данный объект не содержит данных, что в целом корректно позволит показать пустую форму.
  5. В рамках обработчика запроса на добавление нового треугольника реализуйте проверку параметров формы с помощью линзы для всей формы.
    1. Обработайте запрос от пользователя с помощью линзы формы.
    2. Если в результате проверки формы в полученном объекте WebForm находятся ошибки (список ошибок не пуст), то необходимо показать пользователю HTML-документ с формой. Передайте полученный от линзы экземпляр класса WebForm в модель для отображения информации.
    3. Если в результате проверки формы нет ошибок, то необходимо создать новый объект Triangle, передав ему в конструктор параметры, полученные от пользователя. Используйте линзы FormField для извлечения данных из объекта WebForm.
  6. Модифицируйте шаблон отображения формы таким образом, чтобы он отображал данные из передаваемого объекта WebForm.
    1. Используйте свойство errors для отображения списка ошибок, которые были получены в результате проверки формы. Ошибки можно вывести либо:
      • Общим списком перед формой (к сожалению без локализации на русский язык)
      • Подсвечиванием полей, которые содержат ошибки. Для идентификации таких полей необходимо пройтись по списку ошибок. В мета-информации ошибки записано название поля, которое стало источником данной ошибки.
    2. Используйте свойство fields для отображения данных, которые были введены пользователем при отправке формы.

Задача № 4. Использование линз для фильтрации #

Реализуйте проверку данных, приходящих от формы фильтрации и сортировки данных, с использованием линз. Данная форма отправляет данные через передачу параметров внутри запроса URI.

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