How to return a value inside or outside a Spring Webflux Mono Subscribe depending on specific test result inside the subscribe

huangapple go评论81阅读模式
英文:

How to return a value inside or outside a Spring Webflux Mono Subscribe depending on specific test result inside the subscribe

问题

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 work and how to respect best practices, i.e., not to have 2 return statements in my method.

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

英文:

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;
		
	}

}

答案1

得分: 2

你可能需要调用 Mono.flatMap()。它需要作为参数一个从第一个 Mono 的结果到另一个 Mono 的对象的函数,并返回一个 Mono。如果你正在寻找调用链(调用服务A,然后服务B,并获取服务B的响应)- 这是 Mono.flatMap() 的典型用例。

英文:

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().

答案2

得分: 2


我看不到`java.util.stream.*`的使用和需要虽然它们可以共存/交互但没有必要复杂化),但这里是你方法的一个示例,`String`)版本

public Mono<String> compute(String first, String second, String third) {
    Mono<String> firstResponse = 
        // 仅为演示,实际中调用真实的服务:
        Mono.just(first);
    return firstResponse.flatMap(s -> { // !
        if (s.equals("Hello")) { // 一些(演示)条件
            Mono<String> secondResponse = 
                // 仅为演示,实际中调用真实的服务:
                Mono.just(s + second + third);
            return secondResponse;
        } else {
            return Mono.just(";("); // Mono.empty()/抛出异常/...
        }
    });
}


1.`firstResponse`发出的项目等于`"Hello"`返回`secondResponse`(即满足某些条件)。
2. 否则返回`Mono`(发布者”)`";("`(伤心表情:)

去掉注释和演示变量后它是一个一行代码”)。

这是一个相应的junit5反应器测试的样子

@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);
}

因此重点关注[`flatMap`][1]操作符
> *异步*转换此Mono发出的项目返回另一个Mono发出的值

[`map`][2]操作符相反它在*同步*时执行相同的操作返回**而不是Mono/Publisher..例如`secondResponse`阻塞/`String`而不是`Mono<String>`

有用的链接
- [核心参考文档(#which-operator?)][3] 
- [测试参考文档](https://projectreactor.io/docs/core/release/reference/index.html#testing)


  [1]: https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html#flatMap-java.util.function.Function-
  [2]: https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html#map-java.util.function.Function-
  [3]: https://projectreactor.io/docs/core/release/reference/#which-operator
英文:

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 <s>the value emitted by</s> 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&lt;String&gt;)

Useful Links:

huangapple
  • 本文由 发表于 2023年6月8日 00:53:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76425541.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定