2017-06-22 25 views
5

我有一個被動rest api(webflux),也使用spring WebClient類來請求來自其他休息服務的數據。Spring Reactive 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) 

} 

換句話說:我明白了(幾乎)所有的單獨的反應的例子,但我不能把它一起,構建一個簡單的用例(獲得 - >驗證 - >保存 - >返回),而不會阻塞對象。


越接近我能得到的是:

@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); 
    } 

附配的方法是:

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); 
    } 

我使用了Netty,SpringBoot,春WebFlux和無功蒙戈庫。但有一些問題:

1)我收到錯誤: java.lang.IllegalStateException:只有一個連接接收訂閱者允許。也許是因爲我正在使用相同的documentRequest來轉換和setDocumentOwner。我真的不知道。

2)setDocumentOwner方法沒有被調用。所以要保存的文檔對象不會更新。我相信可以有更好的方法來實現這個setDocumentOwner()。

謝謝

+0

隨着錯誤消息解釋,獲取的響應時,你不能指望一個'Mono'返回類型與服務器發送事件的內容類型。如果你期待一個單一的JSON對象,那麼''application/json''會更適合。請先解決此問題,然後更新您的問題。 –

+0

@BrianClozel,完美!我編輯了我的問題。 –

+0

已編輯的問題。 –

回答

2

我真的不明白這個問題的驗證方面。 但它看起來像你試圖組合反應型。這是反應堆與操作員完美結合的事情。

當然,還有更好的方法來處理程序的情況下,但在Mono API makes me think about this快速搜索:

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); 
+0

布賴恩,事情對我來說已經變得很清楚,但我認爲我需要在我的使用案例中更深入。我將編輯我的問題。提前致謝。 –

+0

編輯的問題。 –

+0

你的編輯並沒有讓事情變得更容易處理。我們現在得到了許多不相關的類型'Processo','Document','Classe','DocumentOwner'。你能否重做它,使它成爲一個單一的問題陳述? –

相關問題