如何使顺序API调用并合并结果
我尝试进行顺序的API调用,并将结果合并为单声道。第一个API包含第二个API的ID列表。
@Service
@AllArgsConstructor
public class AggregateService {
private OperationClient operationClient;
private OuvrageClient ouvrageClient;
public Mono<OperationDetailDto> getDetails(String operationId){
final Mono<OperationFullDto> operationMono = operationClient.getOperation(operationId);
return operationMono
.flatMap(operation -> {
final OperationDetailDto detail = new OperationDetailDto();
final Mono<List<OuvrageDto>> ouvrageMono = ouvrageClient.getOuvrages(operation.getOuvrageIds());
Mono<Tuple2<OperationFullDto, List<OuvrageDto>>> tuple2 = Mono.zip(operationMono,ouvrageMono);
tuple2.map(result ->{
detail.setId(ServiceUtils.formatUuid(operationId));
detail.setTitre(result.getT1().getTitre());
detail.setOuvrages(result.getT2());
return detail;
});
return Mono.just(detail);
}
);
}
}
我的功能性网络
@Service
public class OperationClient {
private final WebClient webClient;
public OperationClient(WebClient.Builder builder) {
this.webClient = builder.baseUrl("lb://operation-microservice/operation/").build();
}
public Mono<OperationFullDto> getOperation(String operationId){
return webClient
.get()
.uri("{id}" , operationId)
.retrieve()
.bodyToMono(OperationFullDto.class)
.subscribeOn(Schedulers.parallel())
.log()
.onErrorResume(ex->Mono.empty());
}
}
限制了OuvrageClient被调用了,但我看不到日志
public class OuvrageClient {
private final WebClient webClient;
public OuvrageClient(WebClient.Builder builder) {
this.webClient = builder.baseUrl("lb://ouvrage-microservice/ouvrage/").build();
}
public Mono<List<OuvrageDto>> getOuvrages(List<Long> ids){
System.out.println("the void getOuvrages was invoked " + ids );
return webClient
.get()
.uri("multi/{ids}",ids)
.retrieve()
.bodyToFlux(OuvrageDto.class)
.subscribeOn(Schedulers.parallel())
.collectList()
.onErrorReturn(Collections.emptyList())
.log();
}
}
登录
2022-06-21 10:54:37.872 INFO 252 --- [ctor-http-nio-3] reactor.Mono.SubscribeOn.1 : onSubscribe(MonoSubscribeOn.SubscribeOnSubscriber)
2022-06-21 10:54:37.875 INFO 252 --- [ctor-http-nio-3] reactor.Mono.SubscribeOn.1 : request(unbounded)
2022-06-21 10:54:38.724 INFO 252 --- [ctor-http-nio-1] reactor.Mono.SubscribeOn.1 : onNext(OperationFullDto(id=c4f62ea6-0387-4021-b5de-d056105612ce, titre=test3, ouvrageIds=[2]))
the void getOuvrages was invoked [2]
2022-06-21 10:54:38.796 INFO 252 --- [ctor-http-nio-1] reactor.Mono.SubscribeOn.1 : onComplete()
outovrageClient被调用,但我看不到ouvrageclient的log ........我的聚合服务的全局结果是空的,
{"id": null,"titre": null,"ouvrages": null}
谢谢您
的答案! 您如何看待这件代码?
public Mono<OperationDetailDto> getDetails(String operationId){
final Mono<OperationFullDto> operationMono = operationClient.getOperation(operationId);
return operationMono.zipWhen( operation -> ouvrageClient.getOuvrages(operation.getOuvrageIds()) )
.map( tuple2 -> {
OperationDetailDto detail = new OperationDetailDto();
detail.setId(ServiceUtils.formatUuid(operationId));
detail.setTitre(tuple2.getT1().getTitre());
detail.setOuvrages(tuple2.getT2());
return detail;
});
}
I try to make sequential API calls and merge the result in a mono . The first API contains a List of Id for the second API.
@Service
@AllArgsConstructor
public class AggregateService {
private OperationClient operationClient;
private OuvrageClient ouvrageClient;
public Mono<OperationDetailDto> getDetails(String operationId){
final Mono<OperationFullDto> operationMono = operationClient.getOperation(operationId);
return operationMono
.flatMap(operation -> {
final OperationDetailDto detail = new OperationDetailDto();
final Mono<List<OuvrageDto>> ouvrageMono = ouvrageClient.getOuvrages(operation.getOuvrageIds());
Mono<Tuple2<OperationFullDto, List<OuvrageDto>>> tuple2 = Mono.zip(operationMono,ouvrageMono);
tuple2.map(result ->{
detail.setId(ServiceUtils.formatUuid(operationId));
detail.setTitre(result.getT1().getTitre());
detail.setOuvrages(result.getT2());
return detail;
});
return Mono.just(detail);
}
);
}
}
My functional WebClient
@Service
public class OperationClient {
private final WebClient webClient;
public OperationClient(WebClient.Builder builder) {
this.webClient = builder.baseUrl("lb://operation-microservice/operation/").build();
}
public Mono<OperationFullDto> getOperation(String operationId){
return webClient
.get()
.uri("{id}" , operationId)
.retrieve()
.bodyToMono(OperationFullDto.class)
.subscribeOn(Schedulers.parallel())
.log()
.onErrorResume(ex->Mono.empty());
}
}
The ouvrageClient was invoked but I don't see log
public class OuvrageClient {
private final WebClient webClient;
public OuvrageClient(WebClient.Builder builder) {
this.webClient = builder.baseUrl("lb://ouvrage-microservice/ouvrage/").build();
}
public Mono<List<OuvrageDto>> getOuvrages(List<Long> ids){
System.out.println("the void getOuvrages was invoked " + ids );
return webClient
.get()
.uri("multi/{ids}",ids)
.retrieve()
.bodyToFlux(OuvrageDto.class)
.subscribeOn(Schedulers.parallel())
.collectList()
.onErrorReturn(Collections.emptyList())
.log();
}
}
Log
2022-06-21 10:54:37.872 INFO 252 --- [ctor-http-nio-3] reactor.Mono.SubscribeOn.1 : onSubscribe(MonoSubscribeOn.SubscribeOnSubscriber)
2022-06-21 10:54:37.875 INFO 252 --- [ctor-http-nio-3] reactor.Mono.SubscribeOn.1 : request(unbounded)
2022-06-21 10:54:38.724 INFO 252 --- [ctor-http-nio-1] reactor.Mono.SubscribeOn.1 : onNext(OperationFullDto(id=c4f62ea6-0387-4021-b5de-d056105612ce, titre=test3, ouvrageIds=[2]))
the void getOuvrages was invoked [2]
2022-06-21 10:54:38.796 INFO 252 --- [ctor-http-nio-1] reactor.Mono.SubscribeOn.1 : onComplete()
The ouvrageClient was invoked but I don't see log for the ouvrageClient .... and the global result of my AggregateService is empty
{"id": null,"titre": null,"ouvrages": null}
Thanks
Thanks for the answer !
what do you think of this piece of code?
public Mono<OperationDetailDto> getDetails(String operationId){
final Mono<OperationFullDto> operationMono = operationClient.getOperation(operationId);
return operationMono.zipWhen( operation -> ouvrageClient.getOuvrages(operation.getOuvrageIds()) )
.map( tuple2 -> {
OperationDetailDto detail = new OperationDetailDto();
detail.setId(ServiceUtils.formatUuid(operationId));
detail.setTitre(tuple2.getT1().getTitre());
detail.setOuvrages(tuple2.getT2());
return detail;
});
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以将
tuple2.map
返回flatmap
操作,但请确保在map
中确保创建并返回
operationdetaildto
/code>的lambda。You could return the
tuple2.map
to theflatMap
operation directly, but make sure you create and return theOperationDetailDto
inside themap
's lambda.