Spring Reactive WebClient

Igo*_*oso 5 java project-reactor reactive

我有一个反应式休息api(webflux),也使用spring WebClient类,从其他休息服务请求数据.

简化设计:

@PostMapping(value = "/document")
public Mono<Document> save(@RequestBody Mono<Document> document){

//1st Problem: I do not know how to get the documentoOwner ID 
//that is inside the Document class from the request body without using .block()
    Mono<DocumentOwner> documentOwner = documentOwnerWebClient()
       .get().uri("/document-owner/{id}", document.getDocumentOwner().getId())
       .accept(MediaType.APPLICATION_STREAM_JSON)
       .exchange()
       .flatMap(do -> do.bodyToMono(DocumentOwner.class));

    //2nd Problem: I need to check (validate) if the documentOwner object is "active", for instance
    //documentOwner and document instances below should be the object per se, not the Mono returned from the external API
    if (!documentOwner.isActive) throw SomeBusinessException();

    document.setDocumentOwner(documentOwner);

    //Now I can save the document in some reactive repository, 
    //and return the one saved with the given ID.
    return documentRepository.save(document)

}
Run Code Online (Sandbox Code Playgroud)

换句话说:我理解(几乎)单独的所有反应示例,​​但我无法将它们全部放在一起并构建一个简单的用例(get - > validate - > save - > return)而不会阻塞对象.


我越接近的是:

@PostMapping(value = "/document")
    public Mono<Document> salvar(@RequestBody Mono<Document> documentRequest){

        return documentRequest
                .transform(this::getDocumentOwner)
                .transform(this::validateDocumentOwner)
                .and(documentRequest, this::setDocumentOwner)
                .transform(this::saveDocument);
    }
Run Code Online (Sandbox Code Playgroud)

辅助方法有:

private Mono<DocumentOwner> getDocumentOwner(Mono<Document> document) {
        return document.flatMap(p -> documentOwnerConsumer.getDocumentOwner(p.getDocumentOwnerId()));
    }

    private Mono<DocumentOwner> validateDocumentOwner(Mono<DocumentOwner> documentOwner) {

        return documentOwner.flatMap(do -> {
            if (do.getActive()) {
                return Mono.error(new BusinessException("Document Owner is Inactive"));
            }
            return Mono.just(do);
        });


    }

    private DocumentOwnersetDocumentOwner(DocumentOwner documentOwner, Document document) {
        document.setDocumentOwner(documentOwner);
        return document;
    }

    private Mono<Document> saveDocument(Mono<Document> documentMono) {
        return documentMono.flatMap(documentRepository::save);
    }
Run Code Online (Sandbox Code Playgroud)

我正在使用Netty,SpringBoot,Spring WebFlux和Reactive Mongo Repository.但是有一些问题:

1)我收到错误:java.lang.IllegalStateException:只允许一个连接接收订阅者.也许是因为我使用相同的documentRequest转换和setDocumentOwner.我真的不知道.

2)没有调用setDocumentOwner方法.因此,不保存要保存的文档对象.我相信可以有更好的方法来实现这个setDocumentOwner().

谢谢

Bri*_*zel 2

我不太明白这个问题的验证方面的意义。但看起来您正在尝试将反应类型组合在一起。这是反应堆与操作员完美处理的事情。

当然有更好的方法来处理这种情况,但是在MonoAPI 中的快速搜索让我想到了这一点

Mono<Document> document = ...
Mono<DocumentOwner> docOwner = ...
another = Mono.when(document, docOwner)
              .map(tuple -> {
                        Document doc = tuple.getT1();
                        DocumentOwner owner = tuple.getT2();
                        if(owner.getActive()) {
                          return Mono.error(new BusinessException("Document Owner is Inactive"));
                        }
                        doc.setDocumentOwner(owner);
                        return doc;
              })
              .flatMap(documentRepository::save);
Run Code Online (Sandbox Code Playgroud)