Васильев Андрей Михайлович
Версии презентации
Библиотека предоставляет класс org.http4k.core.Uri, с помощью которого описываются пути в запросах и ответах
Объекты класса можно создать с помощью:
of, которой передаётся строкаВ обработчиках HTTP-запросов URI находится в свойстве uri объекта-запроса
С помощью Uri-объекта можно получить доступ к следующим частям URI:
pathqueryschemehostВсю логику по обработке всех возможных запросов можно реализовать в рамках одного обработчика HTTP-запросов, функциональном типе HttpHandler, но
Решение проблемы — разделение обработки HTTP-запросов между разными обработчиками, выделение слоя маршрутизации
/Функция может быть помечена ключевым словом infix, если
Описание инфиксной функции и её использование
infix fun Int.shl(x: Int): Int { /*...*/ }
1 shl 2
1.shl(2)Обязательно указывать как получателя, так и параметр
Функция routes
позволяет связать HTTP-обработчики с маршрутами
val handlerOne: HttpHandler = { Response(OK).body("First response") }
val handlerTwo: HttpHandler = { Response(OK).body("Second response") }
val app = routes(
"first" bind GET to handlerOne,
"second".bind(GET).to(handlerTwo),
)handlerOne и handlerTwo являются обработчиками, HttpHandler/first и /secondapp был помещён HTTP-обработчик, его тип RoutingHttpHandlerdescriptionroutes(
"bob" bind GET to { Response(OK).body("you GET bob") },
"rita" bind POST to { Response(OK).body("you POST rita") },
"sue" bind DELETE to { Response(OK).body("you DELETE sue") },
)bind
связывает строку с методом по его обработке, возвращая объект типа
PathMethodPathMethod.to
связывает результат работы предыдущего метода с обработчиками запроса, порождая
объект типа
RoutingHttpHandlerСформированный список объектов RoutingHttpHandler передаётся на вход функции routes, которая сама возвращает обработчик RoutingHttpHandler
http4k поддерживает следующие HTTP-методы: GET, POST, PUT, DELETE, OPTIONS, TRACE, PATCH, PURGE, HEAD. Методы описаны в перечислении org.http4k.core.Method
Функции routes в качестве аргумента можно передать объект RoutingHttpHandler, созданный в результаты другого вызова функции routes:
val webCourseRouter = routes(
"topic" bind GET to { Response(OK).body("Веб-разработка") },
"length" bind GET to { Response(OK).body("1 семестр") }
)
val unixCourseRouter = routes(
"topic" bind GET to { Response(OK).body("Использование UNIX") },
"length" bind GET to { Response(OK).body("1 или 2 семсетра")},
)
val coursesApp = routes(
"test/ping" bind GET to { Response(OK).body("pong") },
"unix" bind unixCourseRouter,
"web" bind webCourseRouter,
)Обрабатываются маршруты:
/test/ping/unix/topic, /unix/length/web/topic, /web/lengthВ рамках строки-шаблона могут содержаться переменные, которые можно использовать в рамках обработки запроса
routes (
"/book/{title}" bind GET to { request ->
Response.invoke(Status.OK).body(request.path("title").orEmpty())
},
"/author/{name}/latest" bind GET to { request ->
Response.invoke(Status.OK).body(request.path("name").orEmpty())
},
)/ для разделения: /book/{author}/{title}RoutedRequestRequest.path
fun Request.path(name: String): String?String?.orEmpty() возвращает пустую строку, если ссылка содержит nullЗачастую информации из запроса недостаточно для формирования ответа:
Для решения этих задач в конструктор обработчика надо передать зависимости:
// Конструктор в виде класса
class UserListerHandler(private val users: List<String>): HttpHandler {
override fun invoke(request: Request): Response =
Response(OK).body(users.joinToString(", "))
}
val userHandler = UserListerhandler(listOf("Иван", "Марья"))
// Констуктор в виде функции-генератора
fun messageResponder(message:String): HttpHandler = {
Response(OK).body(message)
}
val messageHandler = messageResponder("Привет!")Если объекты-обработчики создаются внутри маршрутизатора, то их необходимо передать через слой маршрутизатора тоже
Под архитектурой подразумевается вопрос грамотного разделения приложения на компоненты, каждый из которых решает чётко поставленную задачу. Т.е. так, чтобы из небольших компонентов составлять полнофункциональное сложное приложение
Компоненты веб-приложения:
Все компоненты соединяются между собой внутри маршрутизатора и коде обработчиков HTTP-запросов