【发布时间】:2021-08-14 00:37:11
【问题描述】:
所以我有一个简单的@RestController 端点,我想在其中使用 WebClient 进行 API 调用,然后获取从该调用中获得的数据,进行更多 API 调用、处理数据和最终返回一些基于所有这些的数据......
然而,这整个反应式的事情让我很困惑。我知道如何使用RestTemplate 以旧方式执行此操作,没问题......我想这正是使用block() 等待客户端完成然后我可以使用它的时候数据,但显然这在“反应式”控制器中是不允许的!
我创建了一个自定义 POJO (ExternalApiResponse),它与来自 API 的 JSON 数据响应相匹配,这似乎工作正常...以下代码可以正常工作,并且完美地响应来自的 JSON 数据API 调用并在从外部 API 获取后在浏览器中显示...
这个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;
}
}
我认为有一种更合适的方式来构建它,但我不确定。非常感谢任何潜在客户!
【问题讨论】:
-
我认为解决方案是使用
map()或flatMap(),但我所做的每一次尝试都失败了! :// -
对单声道进行平面映射,从对象中获取列表将其放入 Flux.fromIterable,然后再次对从通量发出的每个项目进行平面映射。在该 flatMap 中,为每个项目执行一个新的 webclient 调用。
-
使用
flatMap将简单地合并/展平您在此过程中检索到的每个响应。但是,您说“进行更多的 API 调用,处理数据,并最终根据所有这些返回一些数据” - 这意味着flatMap实际上可能是错误的方法。也许你应该简单地subscribe()到 Mono,然后进行 API 调用,subscribe()到那个,然后继续下去,直到你处理数据。最后从每个subscribe()返回结果,让它一直冒泡返回客户端。 -
我在读到 subscribe 不应该在这里使用,这不正确吗?我在这里严重不知道正确的语法,我无法弄清楚如何使用 flatMap 或 map 从单个响应中提取列表(或数组,我都尝试过)!一个小的语法示例将大大帮助我度过美好的一天!
-
这似乎可以将集合提取到它自己的 CollectionType Mono... Mono
collect = response.map(c -> c.getCollection());但是我不知道该怎么做才能遍历它们!
标签: java spring-boot spring-webflux spring-webclient