Зависимые вызовы веб-клиентов - Spring Reactive - PullRequest
0 голосов
/ 04 мая 2020

Я пытаюсь сделать два вызова API, второй вызов API зависит от первого ответа API. Следующий фрагмент кода дает ответ на первый вызов weblient. Здесь я не получаю ответ от второго вызова API. В журнале я увидел, что запрос на второй вызов веб-клиента даже не запускается с onSubscribe (). Подскажите, пожалуйста, какую ошибку я делаю.

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

ОБНОВЛЕНИЕ 2:

Я изменил свой код на Функции и использовал Flux вместо потоковых итераций. Сейчас я сталкиваюсь с тем, что все итерации отфильтровываются в методе doSecondCall. Пожалуйста, обратитесь мой комментарий в методе doSecondCall. Из-за чего второй звонок не срабатывает. Если я не применяю фильтр, появляются запросы, запускаемые как «Issue / NULL», что также приводит к отключению моего сервиса 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();

   }

[ Как Реактивное программирование с использованием WebFlux обрабатывает зависимые внешние API звонит ] @ Thomas- Также, только что нашел эту тему. По сути, он говорит, что если вы не заблокируете первый вызов, нет способа объявить второй. Это тот случай?

1 Ответ

2 голосов
/ 04 мая 2020

Почему вы не запускаете вторые вызовы, потому что вы разрываете цепочку, как я упоминал в этом ответе (с примерами).

Прекратите разрывать цепочку

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

Вы должны использовать больше функций, чтобы разделить ваш код. Сделайте это привычкой, написав функцию, и всегда начинайте с оператора return. Ваш код очень трудно читать.

Я думаю, что вам следует вместо этого использовать FLux вместо итерации потока.

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