简体   繁体   English

相关的 webclient 调用 - Spring Reactive

[英]Dependant webclient calls - Spring Reactive

I am trying to do two API calls, the second API call is dependent on the first API response.我正在尝试执行两个 API 调用,第二个 API 调用取决于第一个 API 响应。 The following piece of code gives response for first weblient call.Here I am not getting the response from second API call.以下代码给出了第一个 weblient 调用的响应。这里我没有得到第二个 API 调用的响应。 On log I could see that the request for the second webclient call is not even started with onSubscribe().在日志中,我可以看到对第二个 Web 客户端调用的请求甚至不是从 onSubscribe() 开始的。 Can you please tell me what mistake am I doing.你能告诉我我做错了什么吗?

@Autowired
Issue issue;

List issueList = new ArrayList<>();

public Mono<Response> getResponse(Request request) {
   return webClient.post()
     .uri("myURI")
     .body(Mono.just(request),Request.class)
     .retrieve()
     .bodyToMono(Response.class)
     .flatMap(resp->{
           resp.getIssues().stream()
              .forEach(issueTemp -> {
                 issue = issueTemp;
                 webClient.get()
                    .uri("mySecondURI" + issueTemp.getId())
                    .retrieve()
                    .bodyToMono(Issue.class)
                     .flatMap(issueTemp2-> {
                        issue.setSummary(issueTemp2.getSummary());
                        return Mono.just(issue);
                     }).log();
           issueList.add(issue);
        });

        Response responseFinal = new Response();
        responseFinal.setIssues(issueList);
        return Mono.just(responseFinal);
    }).log();
}

UPDATE 2:更新 2:

I have changed my code to Functions and used Flux instead of stream iterations.What I am facing now is, all the iterations are get filtered out in doSecondCall method.我已将代码更改为 Functions 并使用 Flux 而不是 stream 迭代。我现在面临的是,所有迭代都在 doSecondCall 方法中被过滤掉。 Please refer my comment in doSecondCall method.请参考我在 doSecondCall 方法中的评论。 Due to which the second call is not triggered.因此不会触发第二个呼叫。 If i dont apply the filter, there are requests triggered like "issue/null" which also causes my service to go down.如果我不应用过滤器,则会触发诸如“问题/空”之类的请求,这也会导致我的 go 服务停止。

 public Mono<Response> getResponse(Request request) {
   return webClient.post()
     .uri("myURI")
     .body(Mono.just(request),Request.class)
     .retrieve()
     .bodyToMono(Response.class)
     .flatMap(r->
         doSecondCall(r).flatMap(issueList->{
             r.setIssues(issueList);
             return Mono.just(r);
           })
     );
}

public Mono<Issue> doSecondCall(Response r) {
          return Flux.fromIterable(r.getIssues())
                      .filter(rf->rf.getId()!=null) //everything gets filtered out
                      .flatMap(issue->getSummary(issue.getId()))
                      .collectList();
  }


public Mono<Issue> getSummary(Response r) {
          return webClient.get()
                       .uri("issue/"+id)
                       .retrieve()
                       .bodyToMono(Issue.class).log();

   }

[ How does Reactive programming using WebFlux handles dependent external api calls ] @Thomas- Also,Just found this thread. [ 使用 WebFlux 的反应式编程如何处理依赖的外部 api 调用] @Thomas-另外,刚刚找到这个线程。 He basically says unless you block the first call, there is no way to declare the second one.他基本上说除非你阻止第一个电话,否则没有办法声明第二个电话。 Is that the case?是这样吗?

Why you are not triggering the second calls is because you are breaking the chain as i have mentioned in this answer (with examples).为什么您不触发第二次呼叫是因为您正在打破链条,正如我在这个答案中提到的(带有示例)。

Stop breaking the chain停止破坏链条

// here...
.forEach(issueTemp -> {
    issue = issueTemp; // and this is just silly? why?
    webClient.get() // Here you are calling the webClient but ignoring the return value, so you are breaking the chain.
        .uri("mySecondURI" + issueTemp.getId())
        .retrieve()
        .bodyToMono(Issue.class)
        .flatMap(issueTemp2-> {
            issue.setSummary(issueTemp2.getSummary());
            return Mono.just(issue); // Return here but you are ignoring this return value
        }).log();
    issueList.add(issue);
});

You should use more functions to divide up your code.你应该使用更多的函数来划分你的代码。 Make it a habit by writing a function and always start with the return statement.通过编写 function 来养成习惯,并始终从 return 语句开始。 You code is very hard to read.您的代码很难阅读。

I think you should instead use a FLux instead of iterating a stream.我认为您应该改用 FLux 而不是迭代 stream。

// something like the following i'm writing by free hand without IDE
// i have no idea what your logic looks like but you should get the point.
Flux.fromIterable(response.getIssues())
   .flatMap(issue -> {
       return getIssue(issue.getId())
           .flatMap(response -> {
               return issue.setSummary(reponse.getSummary());
           });
   }).collectList();

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

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