How to combine Flux and ResponseEntity in Spring Webflux controllers

ovnia :

I use Monos with ResponseEntitys in my Webflux controllers in order to manipulate headers and other response info. For example:

@GetMapping("/{userId}")
fun getOneUser(@PathVariable userId: UserId): Mono<ResponseEntity<UserDto>> {
    return repository.findById(userId)
        .map(User::asDto)
        .map { ResponseEntity.ok(it) }
        .defaultIfEmpty(ResponseEntity.notFound().build())
}

@GetMapping
fun getAllUsers(): Flux<UserDto> {
    return repository.findAllActive().map(User::asDto)
}

both works fine but there are cases where it is required to have ResponseEntity in conjunction with Flux as well. What should the response type be? Is it correct to use ResponseEntity<Flux<T>>?

For example:

@GetMapping("/{userId}/options")
fun getAllUserOptions(@PathVariable userId: UserId): ??? {
    return repository.findById(userId)
        .flatMapIterable{ it.options }
        .map { OptionDto.from(it) }
        // if findById -> empty Mono then:
        //   return ResponseEntity.notFound().build() ?
        // else:
        //   return the result of `.map { OptionDto.from(it) }` ?
}

The behaviour I'd like to achieve here is that getAllUserOptions returns 404 if repository.findById(userId) is an empty Mono, otherwise return user.options as Flux.

Update: repository here is ReactiveCrudRepository

jannis :

Use switchIfEmpty to throw an exception in case the user doesn't exist:

return repository
    .findById(userId)
    .switchIfEmpty(Mono.error(NotFoundException("User not found")))
    .flatMapIterable{ it.options }
    .map { OptionDto.from(it) }

Then with an exception handler translate it to a 404 response.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=83188&siteId=1