简体   繁体   中英

Dependant webclient calls - Spring Reactive

I am trying to do two API calls, the second API call is dependent on the first API response. The following piece of code gives response for first weblient call.Here I am not getting the response from second API call. On log I could see that the request for the second webclient call is not even started with 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:

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. Please refer my comment in doSecondCall method. 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.

 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. 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. You code is very hard to read.

I think you should instead use a FLux instead of iterating a 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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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