Robbo_UK
Robbo_UK

Reputation: 12129

Spring reactive reading web client response

I am in the process of learning about Spring Reactive and have the following basic reactive demo code.

import org.springframework.web.reactive.function.client.WebClient;
// other imports etc

@Slf4j
class WebClientTests {
  private static String baseUrl = "http://localhost:8080";
  private static WebClient client = WebClient.create(baseUrl);
  @Test
  void testWebClient() {
    Instant start = Instant.now();
    Flux.just(1,2,3)
      .map(i -> client.get().uri("/person/{id}", i).retrieve().bodyToFlux(Person.class))
      .subscribe(s -> {
        log.info("subscribed: {}", s);
      });
    log.info("Elapsed time: " + Duration.between(start, Instant.now()).toMillis() + "ms");
  }
}

It outputs the following.

20:32:55.251 [main] DEBUG io.netty.util.ResourceLeakDetector - -Dio.netty.leakDetection.targetRecords: 4
20:32:55.652 [main] INFO com.example.reactive.reactivedemo.WebClientTests - subscribed: MonoFlatMap
20:32:55.652 [main] INFO com.example.reactive.reactivedemo.WebClientTests - subscribed: MonoFlatMap
20:32:55.652 [main] INFO com.example.reactive.reactivedemo.WebClientTests - subscribed: MonoFlatMap
20:32:55.668 [main] INFO com.example.reactive.reactivedemo.WebClientTests - Elapsed time: 84ms

However I am unsure why its not outputting the value of the get request? Its not actually triggering the endpoint.

Upvotes: 1

Views: 959

Answers (1)

Michael Berry
Michael Berry

Reputation: 72254

You almost certainly want to use flatMap(), not map() on your .map(i -> client.get().uri... line.

map() is used for synchronous transformations, where you're returning the actual value you want to map to. You're not returning an actual value - you're returning a publisher from your map method, so that publisher is just returned as is - it's never subscribed to, and since nothing happens until you subscribe, your web request never executes.

flatMap() is used for non-blocking transformations where you return a publisher that emits the value, or values, you want to map to. That publisher is subscribed to as part of your reactive chain, and the value emitted by that publisher passed down the chain to the next operator.

Upvotes: 1

Related Questions