如何在 Spring 反应式 WebClient 中 return Kotlin 协程流
How to return a Kotlin Coroutines Flow in Spring reactive WebClient
Spring 5.2 带来了 Kotlin 协程支持,Spring 反应式 WebClient
在 Kotlin 扩展中获得了协程支持。
我已经创建了将 GET /posts
作为流程公开的后端服务,检查代码 here。
@GetMapping("")
fun findAll(): Flow<Post> =
postRepository.findAll()
在客户端示例中,我尝试使用 WebClient 通过以下方式使用此 api。
@GetMapping("")
suspend fun findAll(): Flow<Post> =
client.get()
.uri("/posts")
.accept(MediaType.APPLICATION_JSON)
.awaitExchange()
.awaitBody()
由于 Flow 类型的 Jackson 序列化而失败。
由于上面表达式中的 awaitXXX 方法,我必须使用 suspend
修饰符才能获得乐趣。
但如果我将正文类型更改为任何,则以下内容有效,请检查 compelete codes。
GetMapping("")
suspend fun findAll() =
client.get()
.uri("/posts")
.accept(MediaType.APPLICATION_JSON)
.awaitExchange()
.awaitBody<Any>()
阅读 spring 参考文档的 the Kotlin Coroutines 后,应将 Flux 转换为 Kotlin 协程 Flow。如何处理 return 类型到 Flow 并在此处删除 suspend
?
Update: return类型改成Flow,这里查看最新的source codes,我觉得可能是[=46=的一部分] 5.2.0.M2。 suspend
修饰符对于 webclient api 中的 2 阶段协程操作是必需的,正如 Sébastien Deleuze 在下面解释的那样。
首先要了解的是,返回 Flow
不需要为处理程序方法本身使用挂起函数。使用 Flow
,挂起函数通常隔离在 lambda 参数中。但是在这个(常见的)用例中,由于 WebClient
2 阶段 API(首先得到响应,然后得到正文)我们需要处理程序方法暂停 awaitExchange
然后将正文设为 Flow
,扩展名 bodyToFlow
:
@GetMapping("")
suspend fun findAll() =
client.get()
.uri("/posts")
.accept(MediaType.APPLICATION_JSON)
.awaitExchange()
.bodyToFlow<Post>()
从 Spring Framework 5.2 M2 和 Spring Boot 2.2 M3 开始支持(参见 related issue). See also my related detailed blog post。
Spring 5.2 带来了 Kotlin 协程支持,Spring 反应式 WebClient
在 Kotlin 扩展中获得了协程支持。
我已经创建了将 GET /posts
作为流程公开的后端服务,检查代码 here。
@GetMapping("")
fun findAll(): Flow<Post> =
postRepository.findAll()
在客户端示例中,我尝试使用 WebClient 通过以下方式使用此 api。
@GetMapping("")
suspend fun findAll(): Flow<Post> =
client.get()
.uri("/posts")
.accept(MediaType.APPLICATION_JSON)
.awaitExchange()
.awaitBody()
由于 Flow 类型的 Jackson 序列化而失败。
由于上面表达式中的 awaitXXX 方法,我必须使用 suspend
修饰符才能获得乐趣。
但如果我将正文类型更改为任何,则以下内容有效,请检查 compelete codes。
GetMapping("")
suspend fun findAll() =
client.get()
.uri("/posts")
.accept(MediaType.APPLICATION_JSON)
.awaitExchange()
.awaitBody<Any>()
阅读 spring 参考文档的 the Kotlin Coroutines 后,应将 Flux 转换为 Kotlin 协程 Flow。如何处理 return 类型到 Flow 并在此处删除 suspend
?
Update: return类型改成Flow,这里查看最新的source codes,我觉得可能是[=46=的一部分] 5.2.0.M2。 suspend
修饰符对于 webclient api 中的 2 阶段协程操作是必需的,正如 Sébastien Deleuze 在下面解释的那样。
首先要了解的是,返回 Flow
不需要为处理程序方法本身使用挂起函数。使用 Flow
,挂起函数通常隔离在 lambda 参数中。但是在这个(常见的)用例中,由于 WebClient
2 阶段 API(首先得到响应,然后得到正文)我们需要处理程序方法暂停 awaitExchange
然后将正文设为 Flow
,扩展名 bodyToFlow
:
@GetMapping("")
suspend fun findAll() =
client.get()
.uri("/posts")
.accept(MediaType.APPLICATION_JSON)
.awaitExchange()
.bodyToFlow<Post>()
从 Spring Framework 5.2 M2 和 Spring Boot 2.2 M3 开始支持(参见 related issue). See also my related detailed blog post。