Issue
What are differences between mono.map and java optional.map.
can it be used combined with Java Optionnal ?
My code is as follows, unfortunately with two warning.
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
//1:Return null or something nullable from a lambda in transformation method.
//2: Too long maps chain. May cause performance overhead.
return Mono.just(exchange.getRequest())
//Warning-1:
.map(ServerHttpRequest::getRemoteAddress)
.map(InetSocketAddress::getAddress)
//Warning-2:
.map(InetAddress::getHostAddress)
.defaultIfEmpty("0.0.0");
}
So in case of an error, I'm going to change it like this.
public Mono<String> resolve(ServerWebExchange exchange) {
return Mono.just(
Optional.of(exchange.getRequest())
.map(ServerHttpRequest::getRemoteAddress)
.map(InetSocketAddress::getAddress)
.map(InetAddress::getHostAddress)
.orElseGet(() -> "0.0.0")
);
}
Do orElseGet and defaultIfEmpty mean the same thing?
What is the best practice for mono to Judge a null value ?
Thanks in advance for your explanations !
UPDATE: I want to make mono.map as elegant as optional.map for judge null values. like optional.map fluent api.
this code is ugly,How to improve it ?
public Mono<String> resolve(ServerWebExchange exchange) {
return Mono.just(exchange.getRequest())
.flatMap(map -> {
if (map.getRemoteAddress() == null) {
return Mono.empty();
} else {
return Mono.just(map.getRemoteAddress());
}
})
.flatMap(map -> {
if (map.getAddress() == null) {
return Mono.empty();
} else {
return Mono.just(map.getAddress());
}
})
.map(InetAddress::getHostAddress)
.defaultIfEmpty("0.0.0");
}
Solution
map takes one item and potentially transforms it into a different item and returns it into the starting context.
Mono/Flux are not allowed to contain null
values. Instead we use Mono.empty()
to represent nothing.
When you put something in a Mono and use map, your code is living in the reactive context which means that the server can optimize its usage of threads to the max.
While in you second example you put something into a Optional<T>
and then do all the transformations outside the reactive context and when you are done you put the result into the reactive context with Mono#just
.
The second example is what i call fake reactive code. Its when people do all the things they want to to using old imperative java and then place the end result in a Mono
.
That is not reactive
The more time you spend inside the reactive context, the more the framework can optimize its resource usage.
In your case you should use the first example and handle the potential null values in each mapping function, by checking for it and returning a Mono.empty()
instead.
Answered By - Toerktumlare
Answer Checked By - Gilberto Lyons (JavaFixing Admin)