1

I'm a beginner in Spring Web flux and in java Stream. I need to call a method that returns a Mono twice depending on the result content of the first call. But I don't know how to make it works and how to respect best practices i.e not to have 2 return statements in my method.

Off course the code below does not work but I want to show the kind of behaviour that I would like to have. But Don't know how to have it in a Stream way...

@Slf4j
@Service
public class Compare {


    @Autowired
    Myservice myService;
    
    
    public Mono<MyResponse> compute(String firstItem,String secondItem, String thirdItem){
        
        // First Comparison between firstItem and secondItem
        Mono<MyResponse> firstResponse = myService.sendRequestToCompare(firstItem,secondItem);
        

        firstResponse.subscribe(result -> { // Issue on the subscribe method according to my IDE
            
            if ((result.getResponse().getStatus().toString() == "NOT_SAME") && (result.getResponse().getErrorCode() == 201)) {
            
            // Second Comparison with a third value if the previous first one does not match
            Mono<MyResponse> secondResponse = myService.sendRequestToCompare(firstItem,thirdItem);          
                return secondResponse; // Error raised in IDE says change to return; or change method retrun type to Mono<MyResponse> which is already the case
                break;              
            }
        }, error -> {
            log.error("The following error happened on getResponse method from myService!", error);
        });
        return firstResponse;
        
    }

}
cknelle
  • 131
  • 1
  • 12
  • Where are you going to get thirdItem from? Is it result of sendRequestToCompare(firstItem,secondItem), i.e. firstResponse result? – gdomo Jun 07 '23 at 17:05
  • please also (little) dive into https://stackoverflow.com/a/513839/592355 (and why `String x == String y` can work out 9 of 10 times, but won't the other time.) – xerx593 Jun 07 '23 at 18:52

2 Answers2

1

You probably have to call Mono.flatMap(). It requires as an argument a function from the first Mono result to another Mono object and returns Mono. If you are looking for chain of calls (call service A, then service B and get service B response) - that's a typical case for the Mono.flatMap().

gdomo
  • 1,650
  • 1
  • 9
  • 18
1

I see no use and need of java.util.stream.* (though they can co-exist/interact, no need to complicate), but here a (sample, String) version of your method:


public Mono<String> compute(String first, String second, String third) {
    Mono<String> firstResponse = 
        // just demo, call real service instead:
        Mono.just(first);
    return firstResponse.flatMap(s -> { // !
        if (s.equals("Hello")) { // some (demo) condition
            Mono<String> secondResponse = 
                // just demo, call real service instead:
                Mono.just(s + second + third);
            return secondResponse;
        } else {
            return Mono.just(";("); // Mono.empty()/throw exception/...
        }
    });
}

It:

  1. returns secondResponse, when the item emitted by firstResponse equals to "Hello" (i.e. meets some condition)
  2. otherwise a Mono (i.e. "publisher") of ";(" (sad emoji:)

(without comments and (demo) variables, it is a "one-liner";)

This how an according (junit5, reactor) test can look like:

@Test
void testMyCompute() {
    testee.compute("Hello", " World", "!")
            .as(StepVerifier::create)
            .expectNext("Hello World!")
            .verifyComplete();

    testee.compute("", "", "")
            .as(StepVerifier::create)
            .expectNext(";(")
            .verifyComplete();

    NullPointerException npe = assertThrows(NullPointerException.class,() -> testee.compute(null, null, null));
    assertNotNull(npe);
}

So most attention on flatMap operator.

Transform the item emitted by this Mono asynchronously, returning the value emitted by another Mono

(In opposite to map operator, which does the same synchronously, returning the value (not a Mono/Publisher) ..e.g. when secondResponse would be "blocking"/String not Mono<String>)

Useful Links:

xerx593
  • 12,237
  • 5
  • 33
  • 64