Использование параметров запроса #

Васильев Андрей Михайлович, 2025

Версии презентации

Параметры в URI-запросах #

Структура URI

[ схема ":" ] [ // источник ] путь [ "?" запрос ] [ "#" фрагмент ]
  • Запрос начинается с обязательного символа ?, знака вопроса
  • В запросе данные могут быть отформатированы любым образом, однако обычно применяется схема с передачей набора параметров
    • параметр — это пара ключ-значение, разделённые знаком =
    • параметры отделяются друг от друга знаком &
http://some.domain/some/path?key1=value1&key2=value2&key3=value3
  • Передаётся 3 пары параметров с именами key1, key2 и key3
  • Значения параметра key1 — это value1, key2 — это value2, key3 — value3

Особенности параметров #

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

Однако есть важное отличие от словаря: клиент может передать несколько параметров с одинаковыми ключами и сервер должен обработать их все

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

Обработка параметров #

Логические типы параметров #

  • Обязательные. При их отсутствии сервер не может выполнить обработку запроса
  • Не обязательные. Их наличие или отсутствие не влияет на обработку запроса
  • Со значением по умолчанию. Если клиент не передал параметр, то сервер использует значение по умолчанию

При наличии ошибки в значении параметра сервер должен сообщить об ошибке

Дополнительные параметры, переданные от клиента, обычно игнорируются

Последовательность обработки #

Для всех параметров, которые ожидает HTTP-сервер, он выполняет следующие проверки:

  1. Переданы ли параметры в запросе от пользователя
  2. Являются ли переданные данные технически корректными (в строке записано число)

Реализация обработки #

Подходы к обработке параметров, приходящих в запросах от пользователя:

  • Обработать запросы внутри обработчика, используя низкоуровневые интерфейсы
  • Реализовать собственную подсистему для обработки параметров для уменьшения дублирования между разными запросами:
    • Реализовать подсистему полностью самостоятельно
    • Интегрировать стороннюю библиотеку с примитивами http4k
  • Использовать механизмы проверки данных, предоставляемые библиотекой http4k

Низкоуровневый доступ к параметрам #

  • В объекте запроса (Request) предоставляется поле uri, содержащее объект класса Uri
  • Класс Uri предоставляет следующие методы для работы с параметрами:
    • Свойство query содержит строку запроса полностью
    • Функция fun query(query: String): Uri позволяет создать новый объект Uri с новым значением запроса
    • Функция fun queries(): Parameters возвращает набор пар ключ-значения
    • Функция-расширение fun Uri.query(name: String, value: String?): Uri позволяет добавить новый параметр к новому Uri-объекту
    • Функция-расширение fun Uri.removeQuery(name: String): Uri позволяет удалить все параметры с указанным ключом, новое состояние сохраняется в возвращаемом объекте типа Uri
  • Класс Parameters представляет собой список параметров ключ-значение
    • Функция-расширение fun Parameters.findSingle(name: String): String? позволяет найти первый параметр с указанным именем
    • Функция-расширение fun Parameters.findMultiple(name: String): List<String?> позволяет найти все значения для параметра с указанным именем

Работа с классом URI #

Получение параметров из запроса #

val queryParameters: Parameters = request.uri.queries()
val maxPrise: String? = queryParameters.findSingle("maxPrise")
// Каждый вызов queries() приводит к разбору строки
val page: String? = request.uri.queries().findSingle("maxPrice")
  • Данные приходят (или не приходят) в строковом виде
  • Из строки-значения надо извлечь данные

Установление новых значений параметр запроса #

Для установки нового значения для параметра надо сначала удалить старые, а после добавить один новый

val newUri = request.uri.removeQuery("data").query("data", "value")

Если не удалить старые, то вместо замены будет добавлена новая пара