在控制器内部使用WebClient进行API调用



所以我有一个简单的@RestController端点,我想在其中使用WebClient进行一个API调用,然后获取从该调用中获得的数据,进行更多的API调用,处理数据,并最终返回一些基于所有这些的数据。。。

然而,这整个反应性的事情把我搞砸了。我知道如何用RestTemplate的旧方法来做这件事,没问题。。。我本以为这正是使用block()等待客户端完成的时候,然后我可以使用该数据,但显然这在";反应性";控制器!

我创建了一个自定义POJO(ExternalApiResponse(,它与API的JSON数据响应相匹配,看起来运行良好。。。以下代码工作时没有任何错误,并使用API调用中的JSON数据进行完美响应,并在从外部API获取JSON数据后将其显示在浏览器中。。。

这个ExternalApiResponse实际上只包含另一个POJO的一个List,因为API调用的结果的格式类似于{ [ ] }(有更好的方法吗?(,这意味着一个数组被包裹在一个对象中。。。我不想只返回API结果,我想迭代它们,甚至对最初返回的API结果中的每个元素进行额外的API调用(其他地方(,然后返回一个已处理的新对象!

@RestController
@RequestMapping
public class Controller {
@RequestMapping("/{id}")
public Mono<ExternalApiResponse> queryApi(@PathVariable String id) {
Mono<ExternalApiResponse> response = webClientBuilder.build()
.get()
.uri(uri)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(ExternalApiResponse.class)

return response;
}
}

我想还有一种更合适的方式来构建它,但我只是不确定。非常感谢任何线索!

@RequestMapping("/{id}")
public Mono<MyApiResponse> queryApi(@PathVariable String id) {
return webClientBuilder
.build()
.get()
.uri(uri)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(ExternalApiResponse.class)
.flatMapIterable(externalApiResponse -> externalApiResponse.getList()) // switch to flux
.flatMap(item -> process(item)) // process each item individually
.collectList() // collect processed items into a list to wrap them
.map(processedItems -> new MyApiResponse(processedItems)); // wrap
}
private Mono<ProcessedItem> process(Item item) {
// todo
}
private static class ExternalApiResponse {
List<Item> list;
}
private static class MyApiResponse {
List<ProcessedItem> processedItems;
}

最新更新