1
votes

With the below implementation, the expectation is that, it would go to switchIfEmpty if Mono<Optional<Item>> is empty, but not working as expected.

public Mono<ServerResponse> getItemById(ServerRequest request) {
        JwtClaim claim = retrieveClaimFromRequest(request);
        String itemId = request.pathVariable("itemId");
        Mono<ServerResponse> notFound = ServerResponse.notFound().build();
        Mono<Optional<Item>> item = Mono.just(itemRepository.findById(Long.parseLong(itemId)));
        return item
                .flatMap(retItem -> ServerResponse.ok().contentType(APPLICATION_JSON).bodyValue(retItem))
                .switchIfEmpty(notFound);
    }
1
Are you sure you want to use a Mono<Optional<Object>>? The bodyValue will be set to an Optional<Item>, not to Item. Also is there a specific reason you are using flatMap instead of map? - Turing85
Also, to what framework does Mono belong? I guess Reactor? - Turing85
@Turing85, you are correct it gives Optional<Item>. What is the best way to handle it? - user1578872
Mono<Item> item = Mono.just(itemRepository.findById(Long.parseLong(itemId)).orElse(null)); could fix it, but is not null-safe. If you expect the findById to return something, you may want to throw an applicable exception by calling orElseThrow(...) instead. - Turing85
I want to return NotFound reponse if it is empty. - user1578872

1 Answers

0
votes

The problem of your current solution is that Optional<Item> is always returned and available, either with the actual content or an empty one, but the instance itself is present there.

The best way is using Mono.justOrEmpty(Optional) which takes Optional as a parameter and creates either an empty Mono or the one with a content:

Mono<Item> item = Mono.justOrEmpty(itemRepository.findById(Long.parseLong(itemId)));

return item.flatMap(retItem -> ServerResponse.ok().build())
           .switchIfEmpty(ServerResponse.notFound().build());

Effectively, it is as same as you flatmap Mono<Mono<Item>> using the result of Optional::orElse:

Mono<Optional<Item>> item = Mono.just(itemRepository.findById(Long.parseLong(itemId)));
    
return item.flatMap(opt -> opt.map(Mono::just).orElse(Mono.empty()))
           ...