Skip to content

Instantly share code, notes, and snippets.

@cueo
Created September 24, 2020 18:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cueo/5184bff42f95afaf5c1ec0f41450bf3f to your computer and use it in GitHub Desktop.
Save cueo/5184bff42f95afaf5c1ec0f41450bf3f to your computer and use it in GitHub Desktop.
Generic Kotlin coroutine to interact with Spring reactive WebClient
package com.cueo.demo.web
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.http.HttpHeaders
import org.springframework.stereotype.Component
import org.springframework.web.reactive.function.BodyInserters
import org.springframework.web.reactive.function.client.WebClient
import org.springframework.web.reactive.function.client.awaitBody
import java.net.URI
@Component
class ReactiveWebClient<Request: Any, Response: Any> {
private val logger: Logger = LoggerFactory.getLogger(javaClass)
private val webClient = WebClient.create()
suspend fun post(uri: URI, requests: List<Request>, headers: HttpHeaders) = coroutineScope {
val headersConsumer = headers(headers)
val deferredResponses = mutableListOf<Deferred<Response>>()
for (request in requests) {
val response: Deferred<Response> = async(start = CoroutineStart.LAZY) {
post(uri, request, headersConsumer)
}
deferredResponses.add(response)
}
deferredResponses.awaitAll().also {
logger.info("All requests completed successfully")
}
}
suspend fun post(uri: URI, request: Request, headers: (HttpHeaders) -> Unit): Response {
return webClient.post()
.uri(uri)
.body(body(request))
.headers(headers)
.retrieve()
.awaitBody()
}
private fun body(request: Request) = BodyInserters.fromValue(request)
// TODO: is there a better way to do this?
private fun headers(headers: HttpHeaders): (HttpHeaders) -> Unit {
return {
for (header in headers) {
it[header.key] = header.value
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment