简体   繁体   中英

How to use kotlin coroutines with reactive spring data

I am trying to migrate some project from Spring Reactor to kotlin coroutines. I have some controller based on spring webflux like that:

@RestController
class Controller(val productRepository: ProductsRepository) {

    @GetMapping("/product")
    fun find(@RequestParam id: String): Mono<Product> {
        return productRepository.findById(id)
    }
}

This controller uses reactive spring data repository:

@Repository
interface ProductsRepository : ReactiveMongoRepository<Product, String>

According to this official documentation - https://docs.spring.io/spring/docs/5.2.0.M1/spring-framework-reference/languages.html#how-reactive-translates-to-coroutines , my function find in controller should be translated to suspend fun and this function should return an instance of Product class instead of reactive Mono wrapper of Product. Something like that:

@RestController
class Controller(val productRepository: ProductsRepository) {

    @GetMapping("/product")
    suspend fun find(@RequestParam id: String): Product {
        return productRepository.findById(id)
    }
}

But my productRepository deals with Mono and Flux, not suspended functions. How should I use spring data abstraction properly in that case?

This can be achieved with the useful kotlinx-coroutines-reactor helper library which provides useful extensions methods for project reactors Publisher to help between converting Mono or Flux to kotlin coroutines.

First add a dependency on

 <dependency>
     <groupId>org.jetbrains.kotlinx</groupId>
     <artifactId>kotlinx-coroutines-reactor</artifactId>
 </dependency>

(if your using spring-boot you do not have to specify a version as it manages it for you)

You can now use kotlinx.coroutines.reactive.awaitFirstOrNull to convert a Mono<Product> to Product? and 'await' the result.

@RestController
class Controller(val productRepository: ProductsRepository) {

    @GetMapping("/product")
    suspend fun find(@RequestParam id: String): Product? {
        return productRepository.findById(id).awaitFirstOrNull()
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM