如何构建可避免嵌套Flux块(Flux <flux <t =“” >>)的反应性架构?

时间:2019-05-30 13:57:04

标签: java mono spring-webflux flux reactor

我正在尝试构建一个应用程序A(例如适配器),该应用程序将:

1)接收带有某些密钥(JSON格式)的POST请求

2)它应该以某种方式修改该密钥并向另一个系统B创建POST请求。

3)应用程序A应该解析应用程序B的响应并修改该响应。

4)之后,我的应用程序A应该回答初始的POST请求。

@RestController
@RequestMapping("/A")
public class Controller {
    @ResponseStatus(HttpStatus.OK)
    @PostMapping(value = "B", consumes = APPLICATION_JSON_VALUE)
    // to return nested Flux is a bad idea here
    private Flux<Flux<Map<String, ResultClass>>> testUpdAcc(@RequestBody Flux<Map<String, SomeClass>> keys) {
        return someMethod(keys);
    }

    // the problem comes here when I will get Flux<Flux<T>> in the return
    public Flux<Flux<Map<String, ResultClass>>> someMethod(Flux<Map<String, SomeClass>> keysFlux) {
        return keysFlux.map(keysMap -> {
                                // do something with keys and create URL
                                // also will batch keys here
                                <...>

                                // for each batch of keys:
                                WebClient.create(hostAndPort)
                                .method(HttpMethod.POST)
                                .uri(url)
                                .body(BodyInserters.fromObject(body))
                                .header(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded")
                                .accept(MediaType.APPLICATION_JSON)
                                .retrieve()
                                .bodyToMono(schema) // response will be parsed into some schema here
                                .retryWhen (// will make a retry mechanism here)

                                // ===== will join all Mono batches into single Flux
                                Flux.concat(...);
                                }
                             );
    }

}

当然,可以通过不将keysFlux读取为Flux并将其读取为Map来解决此问题。但这应该使一切都减少反应,不是吗? :)

    @ResponseStatus(HttpStatus.OK)
    @PostMapping(value = "B", consumes = APPLICATION_JSON_VALUE)
    // to return nested Flux is a bad idea here
    private Flux<Map<String, ResultClass>> testUpdAcc(@RequestBody Map<String, SomeClass> keys) {
        return someMethod(keys);
    }

我还试图在返回请求之前的最后一刻使用block()/ blockFirst(),但出现错误:

block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor...

谢谢您的想法!

2 个答案:

答案 0 :(得分:0)

忘记我的问题-我们可以轻松地使用“ flatMap”代替“ map”。 这样可以解决Flux内部的Flux问题。

答案 1 :(得分:0)

尝试像这样压缩所有助焊剂

Flux.zip(flux1,flux2)

它将创建Tuple2,以便您可以进行flatMap

谢谢,
维玛列什