Provide WebClient#exchange() alternative for Coroutines

This commit adds awaitExchange { } and
exchangeToFlow { } extensions as Coroutines variants for
exchangeToMono() and exchangeToFlux().

Closes gh-25751
This commit is contained in:
Sébastien Deleuze
2020-10-07 10:58:57 +02:00
parent e899397438
commit 7d7ed88739
3 changed files with 70 additions and 5 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
package org.springframework.web.reactive.function.client
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.reactive.asFlow
import kotlinx.coroutines.reactive.awaitFirst
import kotlinx.coroutines.reactive.awaitSingle
import kotlinx.coroutines.reactor.asFlux
import kotlinx.coroutines.reactor.mono
import org.reactivestreams.Publisher
import org.springframework.core.ParameterizedTypeReference
import org.springframework.web.reactive.function.client.WebClient.RequestBodySpec
@@ -70,9 +74,29 @@ inline fun <reified T : Any> RequestBodySpec.body(producer: Any): RequestHeaders
* @since 5.2
*/
@Suppress("DEPRECATION")
@Deprecated("Deprecated since 5.3 due to the possibility to leak memory and/or connections; please," +
"use awaitExchange { } or exchangeToFlow { } instead; consider also using retrieve()" +
"which provides access to the response status and headers via ResponseEntity along with error status handling.")
suspend fun RequestHeadersSpec<out RequestHeadersSpec<*>>.awaitExchange(): ClientResponse =
exchange().awaitSingle()
/**
* Coroutines variant of [WebClient.RequestHeadersSpec.exchangeToMono].
*
* @author Sebastien Deleuze
* @since 5.3
*/
suspend fun <T: Any> RequestHeadersSpec<out RequestHeadersSpec<*>>.awaitExchange(responseHandler: suspend (ClientResponse) -> T): T =
exchangeToMono { mono(Dispatchers.Unconfined) { responseHandler.invoke(it) } }.awaitFirst()
/**
* Coroutines variant of [WebClient.RequestHeadersSpec.exchangeToFlux].
*
* @author Sebastien Deleuze
* @since 5.3
*/
fun <T: Any> RequestHeadersSpec<out RequestHeadersSpec<*>>.exchangeToFlow(responseHandler: (ClientResponse) -> Flow<T>): Flow<T> =
exchangeToFlux { responseHandler.invoke(it).asFlux() }.asFlow()
/**
* Extension for [WebClient.ResponseSpec.bodyToMono] providing a `bodyToMono<Foo>()` variant