title: Combining several REST Call with Spring Webflux
body: <p>I trying to do something with Spring Webflux but I am really confused with some of the reactive concepts.</p>
  
  <p>I have some REST services protected with Form Authentication, before I could call my Business REST Service, I have to call 'login' URL that is provided via Spring Security, pass my credentials and placed the returned Cookie to the further calls to other REST Services.</p>
  
  <p>Below is the Snippet of the call to the REST Business Service....</p>
  
  <pre><code>@RequestMapping(value = "/endpoint1", method = RequestMethod.POST)
  public Mono&lt;String&gt; businessService(@RequestBody ApiManagementWrapper apiManagementWrapper, ServerWebExchange httpRequest) {
      log.info("Handling /enpoint1");
  
      Mono&lt;String&gt; t = fetch(apiManagementWrapper, httpRequest);
  
      return t;
  }
  
  private Mono&lt;String&gt; fetch(ApiManagementWrapper apiManagementWrapper, ServerWebExchange httpRequest) {
      return this.webClientProxy
              .post()
              .uri("http://localhost:8081/something")
              .headers(httpHeaders -&gt;  httpRequest.getRequest().getHeaders())
              .cookies(httpCookies -&gt; httpRequest.getRequest().getCookies())
              .body(BodyInserters.fromPublisher(Mono.just(apiManagementWrapper.getEnterpriseMessage()), Object.class))
              .exchange()
              .flatMap(response -&gt; response.bodyToMono(String.class));
  }
  </code></pre>
  
  <p>which works perfectly my problem is how to combine this to the call login services..</p>
  
  <p>I thought about following login() method...</p>
  
  <pre><code>private void login(ApiManagementWrapper apiManagementWrapper) {
      LinkedMultiValueMap&lt;String, String&gt; formData = new LinkedMultiValueMap&lt;&gt;();
      formData.add("username", "user1");
      formData.add("password", "user1");
  
      Mono&lt;ClientResponse&gt; response =  this.webClientRouteConfirmation
              .post()
              .uri("http://localhost:8383/login")
              .body(BodyInserters.fromFormData(formData))
              .exchange();
  
      response.subscribe(clientResponse -&gt; {
          handleLogin(clientResponse.cookies().getFirst("JSESSION_ID"), apiManagementWrapper);
      });
  }
  
  private void handleLogin(ResponseCookie loginCookie, ApiManagementWrapper apiManagementWrapper){
      Mono&lt;Route&gt; route = loadRoute(apiManagementWrapper.getEnterptiseContext(), loginCookie);
      if(route == null) {
          return;
      }
  }
  
  
  private Mono&lt;Route&gt; loadRoute(EnterpriseContext enterpriseContext, ResponseCookie loginCookie) {
      Mono&lt;Route&gt; route = this.webClientRouteConfirmation
              .get()
              .uri("http://localhost:8383/routes/search/findByServiceIdAndClientId?serviceName=" + enterpriseContext.getTarget() + "&amp;clientName" + enterpriseContext.getSource())
              .cookie("JSESSION_ID", loginCookie.getValue())
              .exchange()
              .flatMap(clientResponse -&gt; clientResponse.bodyToMono(Route.class));
  
      route.subscribe(r -&gt; {
         handleRoute(enterpriseContext, loginCookie);
      });
  }
  </code></pre>
  
  <p>with the 'login()' method I can get the 'JSESSION_ID' Cookie but while it returns a Mono I can't access the Cookie value (well I can with clientResponse.block() but I know it is evil so try not to do it), so I tried to subscribe to clientResponse with a callback, but if I try to do that I will be decoupled from the 'businessService()' method and will not able to return the values I like to...</p>
  
  <p>So what I want to achieve as pseudo-code is following....</p>
  
  <pre><code>@RequestMapping(value = "/endpoint1", method = RequestMethod.POST)
  public Mono&lt;String&gt; businessService(@RequestBody ApiManagementWrapper apiManagementWrapper, ServerWebExchange httpRequest) {
      log.info("Handling /netty1");
  
      Route route = login(apiManagementWrapper);
  
      Mono&lt;String&gt; t = null;
      if(route != null) {
          t = fetch(apiManagementWrapper, httpRequest);
      }
  
      return t;
  }
  </code></pre>
  
  <p>but I have no idea how to go there without using Mono.block()..</p>
  
  <p>It does not make any sense to return 'Route' object from 'handleLogin()' because if I understand Reactive concepts correctly, 'fetch()' method will not wait for it anyway.... </p>
  
  <p>Any tips?</p>