java - 在 Controller 中使用 WebClient 进行 API 调用
问题描述
所以我有一个简单的@RestController
端点,我想在其中使用 WebClient 进行 API 调用,然后获取从该调用中获得的数据,进行更多 API 调用,处理数据,并最终返回一些基于数据的数据在这一切...
然而,这整个反应性的事情让我很困惑。我知道如何以旧方式执行此操作RestTemplate
,没问题......我会认为这正是block()
等待客户端完成然后我可以使用该数据的时间,但显然这是不允许在“反应式”控制器内部!
我创建了一个自定义 POJO ( ExternalApiResponse
),它与来自 API 的 JSON 数据响应相匹配,它似乎工作正常......以下代码没有错误,并且完美地响应来自 API 调用的 JSON 数据并显示它从外部 API 获取后在浏览器中...
这ExternalApiResponse
实际上只包含List
另一个 POJO,因为来自 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;
}
推荐阅读
- python - 缩写字符串中的单词以符合最大长度
- android - 在 Unity 中禁用 Cardboard 的头部跟踪
- python - Python 编写一个 .txt 文件
- python - 在 IPython 终端中编辑文本文件而不切换终端
- node.js - GraphQL Typescript - 如何检查令牌并将用户添加到请求
- android - 转换错误 Mongodb Nodejs
- sql - 创建月度报告
- bash - 了解 sed 命令
- javascript - React onDrag 对于 screenX/screenY 总是以 0 结尾
- python - 将 python 字典转换为 MATLAB