Spring Webflux - 如何多次从 Mono/Flux 中检索值而不进行多次调用以获取那些 Mono/Flux
Spring Webflux - how to retrieve value from Mono/Flux multiple times without making multiple calls to get those Mono/Flux
我正在使用 Spring Webflux & reactor,Java 11,Spring boot 2.4.5,Spring 5.3.6 版本用于此反应式应用程序。
用例:
我需要调用 API 并从中获取数据。从这些数据中,我获取 uniqueId,然后调用一堆 API 来获取其他数据,最后将所有这些数据组合到新的对象和 return 中。
示例代码:
Mono<Response> 1stAPIResponse = 1stAPI.callMethod(eventId); // response object has ProductId, and other details.
Mono<List<String>> productIds = 1stAPIResponse.map(Response::ProductId).collect(Collectors.toList());
Mono<2ndAPIResponse> 2ndAPIResponse = productIds.flatMap(ids -> 2ndAPI.callMethod(ids));
Mono<3rdAPIResponse> 3rdAPIResponse = productIds.flatMap(ids -> 3rdAPI.callMethod(ids));
...
1stAPIResponse.foreach(response -> {
FinalResponse.builder()
.productId(response.productId)
.val1(2ndAPIResponse.get(response.productId))
.val3(3ndAPIResponse.get(response.productId))
. ...
.build()});
这里的问题是,当 ids 传递给 2ndAPI、3rdAPI、...方法时,它会调用 1stAPI 并每次获取数据.最后,在创建对象时,它会再次调用 1st API。在此示例中,它总共进行了 3 次调用。
如何避免类似的多次调用?
避免这种情况的一种方法是,我可以阻止 1stAPI 呼叫,但它是否正确?它不会破坏非阻塞编码风格吗?
例如:Response 1stAPIResponse = 1stAPI.callMethod(eventId).toFuture().get();
如何编写正确的响应式程序(不阻塞)但仍然只调用 1stAPI?
如有任何问题,请告诉我。
因此,您需要以更具反应性的方式重构代码并使用 zip 运算符进行并行调用:
1stAPI.callMethod(eventId)
.flatmap(response -> // collect your id to list (ids);
return 2ndAPI.callMethod(ids).zipWith(3ndAPI.callMethod(ids))
.flatmap(tuple2 -> FinalResponse.builder() // tuple contains result of 2ndAPI and 3ndAPI
.productId(response.productId)
.val1(2ndAPIResponse.get(response.productId))
.val3(3ndAPIResponse.get(response.productId)))
...
)
我正在使用 Spring Webflux & reactor,Java 11,Spring boot 2.4.5,Spring 5.3.6 版本用于此反应式应用程序。
用例:
我需要调用 API 并从中获取数据。从这些数据中,我获取 uniqueId,然后调用一堆 API 来获取其他数据,最后将所有这些数据组合到新的对象和 return 中。
示例代码:
Mono<Response> 1stAPIResponse = 1stAPI.callMethod(eventId); // response object has ProductId, and other details.
Mono<List<String>> productIds = 1stAPIResponse.map(Response::ProductId).collect(Collectors.toList());
Mono<2ndAPIResponse> 2ndAPIResponse = productIds.flatMap(ids -> 2ndAPI.callMethod(ids));
Mono<3rdAPIResponse> 3rdAPIResponse = productIds.flatMap(ids -> 3rdAPI.callMethod(ids));
...
1stAPIResponse.foreach(response -> {
FinalResponse.builder()
.productId(response.productId)
.val1(2ndAPIResponse.get(response.productId))
.val3(3ndAPIResponse.get(response.productId))
. ...
.build()});
这里的问题是,当 ids 传递给 2ndAPI、3rdAPI、...方法时,它会调用 1stAPI 并每次获取数据.最后,在创建对象时,它会再次调用 1st API。在此示例中,它总共进行了 3 次调用。
如何避免类似的多次调用?
避免这种情况的一种方法是,我可以阻止 1stAPI 呼叫,但它是否正确?它不会破坏非阻塞编码风格吗?
例如:Response 1stAPIResponse = 1stAPI.callMethod(eventId).toFuture().get();
如何编写正确的响应式程序(不阻塞)但仍然只调用 1stAPI?
如有任何问题,请告诉我。
因此,您需要以更具反应性的方式重构代码并使用 zip 运算符进行并行调用:
1stAPI.callMethod(eventId)
.flatmap(response -> // collect your id to list (ids);
return 2ndAPI.callMethod(ids).zipWith(3ndAPI.callMethod(ids))
.flatmap(tuple2 -> FinalResponse.builder() // tuple contains result of 2ndAPI and 3ndAPI
.productId(response.productId)
.val1(2ndAPIResponse.get(response.productId))
.val3(3ndAPIResponse.get(response.productId)))
...
)