I'm a newbie in reactive programming, I have the following rest resource that calls a service that use WebClient to call an existing Rest API :
@PostMapping
public Mono<String> createUser(@RequestBody UserResourceDTO userResourceDto) {
return userService.createUser(userResourceDto);
}
in my service I have the following methode which works fine :
// Working method
public Mono<String> createUser(UserResourceDTO userResourceDTO){
return httpCall(userResourceDTO);
}
when I use this method the HTTP call is triggered and I see it in my log, but since I don't want to return the value from this method I tried the following method :
// Not Working method
public Mono<String> createUser(UserResourceDTO userResourceDTO){
Mono<String> rs = httpCall(userResourceDTO);
return Mono.just("just a value");
// i plan to trigger another call to the DB this is why i don't want to return the result from httpCall
// return userRepository.createUser(userResourceDTO);
}
this method is not working and the HTTP request is not triggered ( i don't see it in the console like the first method), can anyone explain to me why the second method is not triggering the WebClient call and why I'm obliged to return the result from mhttpCall(userResourceDTO);
this is httpCall code :
public Mono<String> httpCall(UserResourceDTO userResourceDTO) {
WebClient webClient = WebClient.create();
KeyCloakUser keyCloakUser = new KeyCloakUser();
// setting values...
return webClient.post()
.uri(new URI("myurl"))
.header("Authorization", "Bearer " toremove)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.body(Mono.just(keyCloakUser), KeyCloakUser.class)
.retrieve()
.bodyToMono(String.class);
}
CodePudding user response:
This is one of the common mistakes after switching to reactive programming. In reactive nothing happens until you subscribe. You need to chain async/sync functions using reactive operators like flatMap
, map
, etc.
Good starting point to understand the concept is Flight of the Flux 1 - Assembly vs Subscription.
Incorrect
public Mono<String> createUser(UserResourceDTO userResourceDTO){
Mono<String> rs = httpCall(userResourceDTO);
return Mono.just("just a value");
}
httpCall(userResourceDTO)
will not be executed as a part of the reactive flow.
Correct
public Mono<String> createUser(UserResourceDTO userResourceDTO){
return httpCall(userResourceDTO)
.then(Mono.just("just a value"));
}
to continue with another async call
public Mono<String> createUser(UserResourceDTO userResourceDTO){
return httpCall(userResourceDTO)
.then(userRepository.createUser(userResourceDTO));
}
or, in case you need result of the HTTP call
public Mono<String> createUser(UserResourceDTO userResourceDTO){
return httpCall(userResourceDTO)
.flatMap(res -> userRepository.createUser(userResourceDTO));
}