简体   繁体   English

如何在 spring webflux/webclient 中有条件地链接 webclient 调用

[英]How do I conditionally chain webclient calls in spring webflux/webclient

I am trying to achieve the following scenario using WebClient.我正在尝试使用 WebClient 实现以下场景。 It is trivial using RestTemplate, but I can't do it anymore.使用 RestTemplate 很简单,但我不能再这样做了。

Relevant parts of a Spring controller in pseudo-java code:伪java代码中Spring controller的相关部分:

Mono<T1> t1 = webClient.get()...retrieve()...;
Mono<T2> t2;

if (t1.getResult().getValue() > 0) {
    t2 = webClient.get().buildUsing(t1.getResult().getValue())...retrieve()...);
} else {
    t2 = Mono.empty();
}

return(Mono.zip(t1, t2, mergeFunction));

I am not asking how to use Webflux.我不是在问如何使用 Webflux。 I can also add error handling myself.我也可以自己添加错误处理。 My problem is how to pass data to the second call if the first call is successful and where to merge results of both calls one of which may or may not happen.我的问题是,如果第一次调用成功,如何将数据传递给第二次调用,以及在哪里合并两个调用的结果,其中一个可能会发生也可能不会发生。 The task is absolutely trivial if I could use RestTemplate.如果我可以使用 RestTemplate,这项任务绝对是微不足道的。

There is a question with a very similar title, but it was not answered.有一个标题非常相似的问题,但没有得到回答。

as far as I could understand your problem, this is my reactive solution to this:据我所知,这是我对此的反应性解决方案:

 private static Mono<String> mono() {
    Mono<Integer> t1 = Mono.just(0);

    return t1.flatMap(outerResult -> outerResult > 0
        ? Mono.just("VALUE").map(innerResult -> outerResult + "" + innerResult)
        : Mono.just(outerResult.toString())
    );
}

So what's happening here:那么这里发生了什么:

With .flatMap you subscribe to a new Mono and take the result of that.使用.flatMap您可以订阅新的Mono并获取结果。 Inside the lambda of the .flatMap you still have the result of your t1 , so you can use .map on t2 , if you need to subscribe, or just do whatever you need to do with the result of t1 to bring it to the wanted return value.在 .flatMap 的.flatMap内部,您仍然拥有t1的结果,因此您可以在t2上使用.map ,如果您需要订阅,或者只是对t1的结果做任何您需要做的事情以将其带到想要的位置返回值。

I think zipWhen fits well for this purpose.我认为zipWhen非常适合这个目的。 zipWhen waits for the result from first mono and then combines both results into a Tuple2 zipWhen等待来自第一个 mono 的结果,然后将两个结果组合成一个Tuple2

WebClient.builder().baseUrl("https://jsonplaceholder.typicode.com/todos/1")
    .build()
    .get()
    .retrieve()
    .bodyToMono(User.class)
    .zipWhen(r -> {
      if (r.getId() == 1) {
        return  WebClient.builder().baseUrl("https://jsonplaceholder.typicode.com/todos/2")
            .build()
            .get()
            .retrieve()
            .bodyToMono(User.class);
      } else {
        return Mono.empty();
      }
    });

The result is a Mono<Tuple2<T, T2>> holding both values.结果是Mono<Tuple2<T, T2>>包含两个值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM