0

I am using Kotlin with Spring Webflux.

I have two functions which extract the some data from the request, makes the extracted data available to the upcoming function.

The example contains only two functions but I have a dozen.

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") 

Usage

 extractQueryParam1(req) { p1 -> extractQueryParam2(req) { p2 -> } } 

The req is somehow like a context for these functions and they share the same context.

What I would like to achieve is somehow to avoid passing the req manually.

Is this achievable in Kotlin? How?

I inspired myself from Akka HTTP in terms of usage. They achieved this using Directives but I haven't go there... yet.

Here is an example: https://doc.akka.io/docs/akka-http/current/routing-dsl/routes.html#route-seal-method-to-modify-httpresponse

1 Answer 1

1

Make them into extension functions, and then you can use with or run scopes to call a series of these without repeatedly passing the parameter.

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") 

Usage:

with(req) { extractQueryParam1 { p1 -> extractQueryParam2 { p2 -> } } } 

Since you're building a DSL, instead of with or run, you might want to write your own scope function that builds the request and then runs the code within its lambda, using the build request as the receiver.

Sign up to request clarification or add additional context in comments.

2 Comments

Can you please elaborate a bit more the latter option?
Maybe in your DSL, there should be an outermost element that creates the request. The higher order function that represents this element could take a lambda with Request receiver. Then when you use it, it would be similar to using with(req) except it would be part of your DSL. I don't know if this make sense with what you're doing as I have never used Spring.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.