Michael Schmid
Michael Schmid

Reputation: 328

Spring WebFlux + Kotlin Response Handling

I'm having some trouble wrapping my head around a supposedly simple RESTful WS response handling scenario when using Spring WebFlux in combination with Kotlin coroutines. Suppose we have a simple WS method in our REST controller that is supposed to return a possibly huge number (millions) of response "things":

@GetMapping
suspend fun findAllThings(): Flow<Thing> {
    //Reactive DB query, return a flow of things
}

This works as one would expect: the result is streamed to the client as long as a streaming media type (e.g. "application/x-ndjson") is used. In more complex service calls that also accounts for the possibility of errors/warnings I would like to return a response object of the following form:

class Response<T> {
    val errors: Flow<String>
    val things: Flow<T>
}

The idea here being that a response either is successful (returning an empty error Flow and a Flow of things), or failed (errors contained in the corresponding Flow while the things Flow being empty). In blocking programming this is a quite common response idiom. My question now is how can I adapt this idiom to the reactive approach in Kotlin/Spring WebFlux?

I know its possible to just return the Response as described (or Mono<Response> for Java users), but this somewhat defeats the purpose of being reactive as the entire Mono has to exist in memory at serialization time. Is there any way to solve this? The only possible solution I can think of right now is a custom Spring Encoder that is smart enough to stream both errors or things (whatever is present).

Upvotes: 0

Views: 515

Answers (1)

Mafor
Mafor

Reputation: 10671

How about returning Success/Error per Thing?

class Result<T> private constructor(val result: T?, val error: String?) {

    constructor(data: T) : this(data, null)
    constructor(error: String) : this(null, error)
    val isError = error != null

}

@GetMapping
suspend fun findAllThings(): Flow<Result<Thing>> {
    //Reactive DB query, return a flow of things
}

Upvotes: 1

Related Questions