ヘッダーやその他の応答情報を操作するために、WebfluxコントローラーでMono
sをResponseEntity
sと一緒に使用しています。例えば:
_@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)
}
_
どちらも正常に機能しますが、ResponseEntity
とFlux
を組み合わせて使用する必要がある場合もあります。応答タイプはどうあるべきですか? _ResponseEntity<Flux<T>>
_を使用することは正しいですか?
例えば:
_@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) }` ?
}
_
ここで達成したい動作は、repository.findById(userId)
が空のMono
の場合、getAllUserOptionsは_404
_を返し、それ以外の場合は_user.options
_をFlux
として返します。
更新:ここのリポジトリはReactiveCrudRepository
です
switchIfEmpty
を使用して、ユーザーが存在しない場合に例外をスローします。
return repository
.findById(userId)
.switchIfEmpty(Mono.error(NotFoundException("User not found")))
.flatMapIterable{ it.options }
.map { OptionDto.from(it) }
次に 例外ハンドラ を使用して、それを404応答に変換します。
ResponseEntityでMonoを返すことで使用できます
このような
public Mono<ResponseEntity<?>> oneRawImage(
@PathVariable String filename) {
// tag::try-catch[]
return imageService.findOneImage(filename)
.map(resource -> {
try {
return ResponseEntity.ok()
.contentLength(resource.contentLength())
.body(new InputStreamResource(
resource.getInputStream()));
} catch (IOException e) {
return ResponseEntity.badRequest()
.body("Couldn't find " + filename +
" => " + e.getMessage());
}
});
}
私もこのような例があります
public ResponseEntity<Mono<?>> newLive(@Valid @RequestBody Life life) {
Mono<Life> savedLive = liveRepository.save(life);
if (savedLive != null) {
return new ResponseEntity<>(savedLive, HttpStatus.CREATED);
}
return new ResponseEntity<>(Mono.just(new Life()), HttpStatus.I_AM_A_TEAPOT);
}
RESTコントローラでの関数型プログラミングは嫌いです。
以下に例を示します ReactiveController 。