[英]Dependant webclient calls - Spring Reactive
我正在嘗試執行兩個 API 調用,第二個 API 調用取決於第一個 API 響應。 以下代碼給出了第一個 weblient 調用的響應。這里我沒有得到第二個 API 調用的響應。 在日志中,我可以看到對第二個 Web 客戶端調用的請求甚至不是從 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:
我已將代碼更改為 Functions 並使用 Flux 而不是 stream 迭代。我現在面臨的是,所有迭代都在 doSecondCall 方法中被過濾掉。 請參考我在 doSecondCall 方法中的評論。 因此不會觸發第二個呼叫。 如果我不應用過濾器,則會觸發諸如“問題/空”之類的請求,這也會導致我的 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-另外,剛剛找到這個線程。 他基本上說除非你阻止第一個電話,否則沒有辦法聲明第二個電話。 是這樣嗎?
為什么您不觸發第二次呼叫是因為您正在打破鏈條,正如我在這個答案中提到的(帶有示例)。
// 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);
});
你應該使用更多的函數來划分你的代碼。 通過編寫 function 來養成習慣,並始終從 return 語句開始。 您的代碼很難閱讀。
我認為您應該改用 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.