Blocking vs Non‑Blocking in Spring: RestTemplate vs WebClient Explained
This article compares Spring's traditional RestTemplate blocking client with the newer reactive WebClient non‑blocking client, explaining their underlying mechanisms, performance differences under concurrency, and provides complete code examples for both approaches, helping developers choose the appropriate tool for efficient HTTP calls.
1. Introduction
In this tutorial we compare Spring's two web client implementations — RestTemplate and the new reactive alternative WebClient.
2. Blocking vs Non‑Blocking Clients
Web applications often need to call other services via HTTP, so a web client tool is required.
2.1 RestTemplate – Blocking Client
For a long time Spring provided RestTemplate as a web client abstraction. Under the hood RestTemplate uses a thread‑per‑request model based on the Java Servlet API.
This means the thread remains blocked until a response is received, consuming memory and CPU cycles. With many concurrent requests, threads accumulate, exhausting the thread pool, increasing memory usage, and causing performance degradation due to frequent context switches.
2.2 WebClient – Non‑Blocking Client
WebClient leverages Spring Reactive Framework's asynchronous non‑blocking solution.
Where RestTemplate creates a new thread for each HTTP request, WebClient creates lightweight tasks that are queued by the reactive framework and executed only when a response is ready.
The reactive framework uses an event‑driven architecture and the Reactive Streams API to compose asynchronous logic, allowing fewer threads and system resources to handle more work.
WebClient is part of Spring WebFlux, offering a fluent functional API and returning reactive types such as Mono and Flux.
3. Comparative Example
To demonstrate the difference we implement two REST endpoints that call a slow service returning a list of tweets. The slow service endpoint is defined as:
@GetMapping("/slow-service-tweets")
private List<Tweet> getAllTweets() {
Thread.sleep(2000L); // delay
return Arrays.asList(
new Tweet("RestTemplate rules", "@user1"),
new Tweet("WebClient is better", "@user2"),
new Tweet("OK, both are useful", "@user1"));
}3.1 Using RestTemplate to call the slow service
Implementation of a blocking endpoint:
@GetMapping("/tweets-blocking")
public List<Tweet> getTweetsBlocking() {
log.info("Starting BLOCKING Controller!");
final String uri = getSlowServiceUri();
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<List<Tweet>> response = restTemplate.exchange(
uri, HttpMethod.GET, null,
new ParameterizedTypeReference<List<Tweet>>() {});
List<Tweet> result = response.getBody();
result.forEach(tweet -> log.info(tweet.toString()));
log.info("Exiting BLOCKING Controller!");
return result;
}When this endpoint is called, the thread blocks until the slow service responds, then logs the tweets.
Starting BLOCKING Controller!
Tweet(text=RestTemplate rules, username=@user1)
Tweet(text=WebClient is better, username=@user2)
Tweet(text=OK, both are useful, username=@user1)
Exiting BLOCKING Controller!3.2 Using WebClient to call the slow service
Implementation of a non‑blocking endpoint:
@GetMapping(value = "/tweets-non-blocking", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Tweet> getTweetsNonBlocking() {
log.info("Starting NON-BLOCKING Controller!");
Flux<Tweet> tweetFlux = WebClient.create()
.get()
.uri(getSlowServiceUri())
.retrieve()
.bodyToFlux(Tweet.class);
tweetFlux.subscribe(tweet -> log.info(tweet.toString()));
log.info("Exiting NON-BLOCKING Controller!");
return tweetFlux;
}The method returns a Flux immediately; the client subscribes to the stream and receives tweets as they become available.
Starting NON-BLOCKING Controller!
Exiting NON-BLOCKING Controller!
Tweet(text=RestTemplate rules, username=@user1)
Tweet(text=WebClient is better, username=@user2)
Tweet(text=OK, both are useful, username=@user1)4. Conclusion
RestTemplate uses the Java Servlet API and is synchronous and blocking. WebClient is asynchronous and does not block the executing thread while waiting for a response. Although RestTemplate remains usable, non‑blocking approaches generally consume far fewer system resources, making WebClient a better choice in many scenarios.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
