依赖网络客户端调用 - Spring 被动
Dependant webclient calls - Spring Reactive
我正在尝试执行两个 API 调用,第二个 API 调用取决于第一个 API 响应。下面的一段代码给出了第一个 weblient call.Here 的响应我没有从第二个 API 调用中得到响应。在日志中,我可以看到对第二个 webclient 调用的请求甚至没有从 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 而不是流 iterations.What 我现在面临的是,所有迭代都在 doSecondCall 方法中被过滤掉。请参考我在 doSecondCall 方法中的评论。因此不会触发第二个调用。如果我不应用过滤器,就会触发像 "issue/null" 这样的请求,这也会导致我的服务中断。
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- 另外,刚找到这个线程。他基本上是说,除非您阻止第一个调用,否则无法声明第二个调用。是这样吗?
为什么你没有触发第二次调用是因为你打破了链条,正如我在这个答案中提到的(有例子)。
// 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();
我正在尝试执行两个 API 调用,第二个 API 调用取决于第一个 API 响应。下面的一段代码给出了第一个 weblient call.Here 的响应我没有从第二个 API 调用中得到响应。在日志中,我可以看到对第二个 webclient 调用的请求甚至没有从 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 而不是流 iterations.What 我现在面临的是,所有迭代都在 doSecondCall 方法中被过滤掉。请参考我在 doSecondCall 方法中的评论。因此不会触发第二个调用。如果我不应用过滤器,就会触发像 "issue/null" 这样的请求,这也会导致我的服务中断。
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- 另外,刚找到这个线程。他基本上是说,除非您阻止第一个调用,否则无法声明第二个调用。是这样吗?
为什么你没有触发第二次调用是因为你打破了链条,正如我在这个答案中提到的(有例子)。
// 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();