2017-06-22 11 views
5

私は、他のレストサービスからのデータを要求するために、スプリングWebClientクラスを使用する反応性の残りのAPI(webflux)を持っています。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) 

} 

:私は個別に(ほぼ)反応例の全てを理解し、私はそれをすべて一緒に入れて、(取得シンプルなユースケースを構築することはできませんよ - > 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); 
    } 

AUXILIAR方法は以下のとおりです。

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

私はネッティー、SpringBoot、春WebFluxと反応Mongoのリポジトリを使用しています。しかし、いくつかの問題があります。

1)私はエラーが発生しています。 java.lang.IllegalStateException:1つの接続だけが加入者を受け取ります。同じ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'をたくさん取得しています。あなたはそれを1つの問題の声明にするためにそれを修正することができますか? –

関連する問題