0

I am trying to understand WebFlux but having some trouble with Webclient calls. I do not see this line System.out.println("customerId = " + customerId); executes it seems like it does not call the endpoint. But if I subscribe to webclient with .subscribe(customer -> {}); then I can see this line System.out.println("customerId = " + customerId); works on the endpoint side. I dont understand why I have to subscribe to Mono call, or do I have to ? Thanks

@GetMapping("/customer/{customerId}")
@ResponseStatus(HttpStatus.ACCEPTED)
public Mono<Void> getCustomer(@PathVariable("customerId") int customerId) {
     WebClient webClient = WebClient.builder().baseUrl("http://localhost:8080").build();

 webClient.get()
  .uri("/client/customer/{customerId}",customerId)
  .accept(MediaType.APPLICATION_JSON)
  .retrieve()
  .bodyToMono(Customer.class);//here do I have to subscribe to actually activate to call?

 return null;
}


@GET
@Path("/customer/{customerId}")
@Produces(MediaType.APPLICATION_JSON)
public Customer getCustomer(@PathParam("customerId") int customerId) throws InterruptedException {
    System.out.println("customerId = " + customerId);  // I do not see the call comes thru if I dont subscribe to flux call.
    return new Customer(customerId,"custName");
} 
Lisa
  • 129
  • 1
  • 1
  • 8
  • 1
    Yes, you have to suscribe. It's a fundamental principle of reactive programming: subscribing is what triggers everything. Nothing happens until you subscribe. https://projectreactor.io/docs/core/release/reference/index.html#reactive.subscribe – JB Nizet Jan 12 '20 at 22:30
  • 1
    But why do you return null from a method supposed to return a Mono? And why is a method called getCustomer returns a Mono? Shouldn't it get a customer? If you actually want to return a Mono, then you will not subscribe. Spring will subscribe for you to the Mono that you return. – JB Nizet Jan 12 '20 at 22:31
  • JB Nizet, you are right. It does not make sense to return a Void. It was just an example which did not care much about return type. Thanks for pointing out though. – Lisa Jan 13 '20 at 02:37
  • If you return the result Mono by webclient, then you do don't need explicit subscribe. – Martin Tarjányi Jan 13 '20 at 12:17

1 Answers1

0

If you want to return the reactive type from your WebClient, you have to return it from your controller method like:

@GetMapping("/customer/{customerId}")
@ResponseStatus(HttpStatus.ACCEPTED)
public Mono<Customer> getCustomer(@PathVariable("customerId") int customerId) {
     WebClient webClient = WebClient.builder().baseUrl("http://localhost:8080").build();

 return webClient.get()
  .uri("/client/customer/{customerId}",customerId)
  .accept(MediaType.APPLICATION_JSON)
  .retrieve()
  .bodyToMono(Customer.class);
}

You can also return a Customer from your endpoint and block and wait for the result of your WebClient and leaving the reactive ecosystem like:

@GetMapping("/customer/{customerId}")
@ResponseStatus(HttpStatus.ACCEPTED)
public Customer getCustomer(@PathVariable("customerId") int customerId) {
     WebClient webClient = WebClient.builder().baseUrl("http://localhost:8080").build();

 return webClient.get()
  .uri("/client/customer/{customerId}",customerId)
  .accept(MediaType.APPLICATION_JSON)
  .retrieve()
  .bodyToMono(Customer.class)
  .block()
}

If you are looking at a general introduction for Spring's WebClient, take a look at this tutorial

rieckpil
  • 10,470
  • 3
  • 32
  • 56