I would like to have a http client to call other microservice from Spring Boot not reactive application. Because of RestTemplate will be deprecated I tried to use WebClient.Builder and WebClient. Though I not sure about thread safety. Here example:
@Service
public class MyService{
@Autowired
WebClient.Builder webClientBuilder;
public VenueDTO serviceMethod(){
//!!! This is not thread safe !!!
WebClient webClient = webClientBuilder.baseUrl("http://localhost:8000").build();
VenueDTO venueDTO = webClient.get().uri("/api/venue/{id}", bodDTO.getBusinessOutletId()).
retrieve().bodyToMono(VenueDTO.class).
blockOptional(Duration.ofMillis(1000)).
orElseThrow(() -> new BadRequestException(venueNotFound));
return VenueDTO;
}
}
serviceMethod() in this example will be called from few threads, and webClientBuilder is a single bean instance. The WebClient.Builder class contains state: baseUrl, and this seems not thread safe as few threads could call this state update simultaneously. Meanwhile WebClient itself seems is thread safe as mentioned in answer at Right way to use Spring WebClient in multi-thread environment
Should I use WebClient.Builder bean as mentioned in https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-webclient.html
Spring Boot creates and pre-configures a WebClient.Builder for you; it is strongly advised to inject it in your components and use it to create WebClient instances.
One of workaround options I see is to create WebClient without any state passed to builder so instead of:
WebClient webClient = webClientBuilder.baseUrl("http://localhost:8000").build();
I will do:
WebClient webClient = webClientBuilder.build();
and pass full url with protocol and port in uri method call:
webClient.get().uri("full url here", MyDTO.class)
What is the proper way to use it in my case?