1

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.

1
  • I would guess because you are not doing anything with the result so perhaps it is optimized out. Commented Jun 6, 2021 at 19:58

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks for the answer. I think you are onto something here however its still not triggering the request?
@Robbo_UK The test is probably finishing before you trigger the request, since you're subscribing but not waiting for the request to finish. If you really want to run the test like this then you should use blockLast() rather than subscribe().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.