如何在Spring响应式WebClient中返回Kotlin协程流

时间:2019-04-15 07:13:19

标签: spring spring-boot kotlin spring-webflux kotlin-coroutines

Spring 5.2带来了Kotlin协程支持,Spring react WebClient在Kotlin扩展中获得了Coroutines支持。

我创建了后端服务,该服务将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 ref doc的the Kotlin Coroutines之后,应将通量转换为Kotlin协程流程。如何处理Flow的返回类型并在此处删除suspend

更新:返回类型已更改为Flow,请在此处检查最新的source codes,我认为它可能是Spring 5.2.0.M2的一部分。 suspend修饰符对于webclient api中的2级协程操作是必需的,如下面SébastienDeleuze所述。

1 个答案:

答案 0 :(得分:1)

首先要了解的是,返回Flow不需要对处理程序方法本身使用暂停函数。对于Flow,挂起函数通常被隔离在lambda参数中。但是在这个(普通)用例中,由于WebClient两阶段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)。另请参阅我的related detailed blog post