#kotlin
Вопрос:
Я использую Kotlin с Spring Webflux.
У меня есть две функции, которые извлекают некоторые данные из запроса, делают извлеченные данные доступными для следующей функции.
Пример содержит только две функции, но у меня их дюжина.
suspend fun extractQueryParam1(serverRequest: ServerRequest,
fn: (p1: String) -> ServerResponse): ServerResponse =
serverRequest.queryParamOrNull("p1")
?.let(fn)
?: badRequestResponse("Missing p1")
suspend fun extractQueryParam2(serverRequest: ServerRequest,
fn: (p1: Long) -> ServerResponse): ServerResponse =
serverRequest.queryParamOrNull("p2")
?.toLong()
?.let(fn)
?: badRequestResponse("Missing p2")
Использование
extractQueryParam1(req) { p1 ->
extractQueryParam2(req) { p2 ->
}
}
Это как req
-то похоже на контекст для этих функций, и они используют один и тот же контекст.
Чего я хотел бы добиться, так это каким-то образом избежать передачи req
вручную.
Возможно ли это в Kotlin? Как?
Я вдохновил себя на использование HTTP Akka с точки зрения использования. Они добились этого с помощью директив, но я туда еще не ходил… пока.
Вот пример: https://doc.akka.io/docs/akka-http/current/routing-dsl/routes.html#route-seal-method-to-modify-httpresponse
Ответ №1:
Превратите их в функции расширения, а затем вы можете использовать with
run
области или для вызова ряда из них без повторной передачи параметра.
suspend fun ServerRequest.extractQueryParam1(
fn: (p1: String) -> ServerResponse): ServerResponse =
queryParamOrNull("p1")
?.let(fn)
?: badRequestResponse("Missing p1")
suspend fun ServerRequest.extractQueryParam2(
fn: (p1: Long) -> ServerResponse): ServerResponse =
queryParamOrNull("p2")
?.toLong()
?.let(fn)
?: badRequestResponse("Missing p2")
Использование:
with(req) {
extractQueryParam1 { p1 ->
extractQueryParam2 { p2 ->
}
}
}
Поскольку вы создаете DSL, вместо with
или run
, возможно, вам захочется написать свою собственную функцию области, которая создает запрос, а затем запускает код в его лямбда, используя запрос на сборку в качестве получателя.
Комментарии:
1. Не могли бы вы, пожалуйста, подробнее остановиться на последнем варианте?
2. Возможно, в вашем DSL должен быть внешний элемент, который создает запрос. Функция более высокого порядка, представляющая этот элемент, может принимать лямбда-код с получателем запроса. Затем, когда вы используете его, он будет похож на использование
with(req)
, за исключением того, что он будет частью вашего DSL. Я не знаю, имеет ли это смысл с тем, что вы делаете, так как я никогда не использовал Весну.