RestTemplate in Spring Boot: Synchronous Communication Between Microservices
RestTemplate is one of the traditional ways to make HTTP calls between microservices in a Spring Boot application.
In a microservices architecture, different services usually run independently and communicate with each other through APIs. For example, an Order Service may need to call a Product Service to retrieve product information.
In this article, we will understand:
- What synchronous communication means
- How two Spring Boot microservices communicate
- How to call REST APIs using plain Java
- What RestTemplate is
- How to configure RestTemplate
- GET, POST, PUT and DELETE operations
exchange()methodexecute()method- HTTP connection and keep-alive
- Limitations of RestTemplate
- Why newer Spring applications may use RestClient
1. What Is Synchronous Communication?
In synchronous communication, the client sends a request to the server and waits for the response before continuing.
For example:
OrderService ---> ProductService
| |
|------ Request -->|
| |
|<----- Response --|
The calling thread waits until the response is received.
Therefore, synchronous communication is generally blocking in nature.
Some common synchronous HTTP communication approaches in Spring Boot include:
- RestTemplate
- RestClient
- FeignClient
2. Example: Two Microservices
Let’s consider two Spring Boot microservices:
OrderService
Port: 8081
ProductService
Port: 8082
The requirement is simple:
OrderService
|
| HTTP Request
↓
ProductService
|
| HTTP Response
↓
OrderService
The ProductService exposes an endpoint such as:
GET http://localhost:8082/products/1
The OrderService will call this endpoint and consume the response.
The original setup uses two independent Spring Boot applications running on different ports.
3. ProductService
Let’s first create a simple Product Service.
@RestController
@RequestMapping("/products")
public class ProductController {
@GetMapping("/{id}")
public String getProduct(@PathVariable String id) {
return "Product fetched with id: " + id;
}
}
For example:
GET http://localhost:8082/products/101
Response:
Product fetched with id: 101
The example in the source document uses the same basic controller structure.
4. Calling REST API Using Plain Java
Before understanding RestTemplate, let’s see what is involved when we make an HTTP call using Java’s lower-level HttpURLConnection.
For example:
String url = "http://localhost:8082/products/" + id;
URL obj = new URL(url);
HttpURLConnection connection =
(HttpURLConnection) obj.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/json");
connection.setConnectTimeout(100);
connection.setReadTimeout(500);
BufferedReader in =
new BufferedReader(
new InputStreamReader(
connection.getInputStream()
)
);
StringBuilder response = new StringBuilder();
String responseLine;
while ((responseLine = in.readLine()) != null) {
response.append(responseLine);
}
in.close();
System.out.println("Response: " + response);
There are several things that need to be handled manually:
- Opening the connection
- Setting the HTTP method
- Setting headers
- Configuring timeouts
- Reading the response
- Closing streams
- Handling exceptions
- Managing the connection lifecycle
The uploaded notes demonstrate this low-level approach and explain how HttpURLConnection works with the underlying TCP connection.
5. Why Do We Need RestTemplate?
Writing all the low-level HTTP communication code manually creates a lot of boilerplate.
For example, we have to manually handle:
Open connection
↓
Set headers
↓
Send request
↓
Read response
↓
Handle response
↓
Close streams
↓
Handle connection
The notes identify several disadvantages of this approach, including manually setting headers, reading responses, closing streams/connections, manually handling responses, and limited convenience around features such as connection pooling and interceptors.
This is where RestTemplate becomes useful.
6. What Is RestTemplate?
RestTemplate is a Spring class that simplifies communication with REST APIs.
Instead of manually creating an HttpURLConnection, reading streams and converting responses, we can write:
String response = restTemplate.getForObject(
"http://localhost:8082/products/" + id,
String.class
);
Much simpler!
The source describes RestTemplate as an abstraction over lower-level HTTP communication and as a traditional approach for calling REST APIs from Spring applications.
7. Creating a RestTemplate Bean
A common approach is to define RestTemplate as a Spring bean.
@Configuration
public class AppConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
Now Spring can inject this RestTemplate wherever it is required.
Configuring Timeouts
We can also configure connection and read timeouts.
@Configuration
public class AppConfig {
@Bean
public RestTemplate restTemplate() {
SimpleClientHttpRequestFactory factory =
new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(1000);
factory.setReadTimeout(5000);
return new RestTemplate(factory);
}
}
The uploaded notes demonstrate both the simple configuration and a configuration using SimpleClientHttpRequestFactory for timeouts.
8. Using RestTemplate in OrderService
Now we can inject RestTemplate into our controller.
@RestController
@RequestMapping("/orders")
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/{id}")
public ResponseEntity<String> getOrder(
@PathVariable String id) {
String response = restTemplate.getForObject(
"http://localhost:8082/products/" + id,
String.class
);
System.out.println(
"Response from Product API: " + response
);
return ResponseEntity.ok("Order call successful");
}
}
The flow is:
Client
|
| GET /orders/101
↓
OrderService
|
| RestTemplate
| GET /products/101
↓
ProductService
|
| Response
↓
OrderService
|
| Response
↓
Client
The example in the uploaded document follows this same OrderService → ProductService flow using getForObject().
9. How Does getForObject() Work?
Consider:
String response = restTemplate.getForObject(
"http://localhost:8082/products/" + id,
String.class
);
Here:
URL
"http://localhost:8082/products/" + id
is the endpoint we want to call.
Response Type
String.class
tells RestTemplate that we expect the response to be converted into a String.
For example, if the API returns:
Product fetched with id: 101
then response contains that value.
10. RestTemplate and TCP Connection Reuse
One important point is that RestTemplate does not simply mean creating and explicitly closing a TCP connection for every call.
The source notes that after the response stream is closed, the underlying connection can be available for reuse depending on the configured connection/idle limits.
This is related to HTTP keep-alive.
With HTTP/1.1, persistent connections are used by default unless the connection is explicitly closed.
For example:
Client
|
| Request 1
|------------------>
|<------------------|
|
| Request 2
|------------------>
|<------------------|
|
| Same connection can potentially be reused
The uploaded notes also explain parameters such as idle timeout and maximum requests for a persistent connection.
11. Important RestTemplate Methods
RestTemplate provides different methods depending on what we need from the HTTP response.
GET – getForObject()
Product product = restTemplate.getForObject(
url,
Product.class
);
It returns the response body as an object.
For example:
Product product =
restTemplate.getForObject(
url,
Product.class
);
12. GET – getForEntity()
If we need the complete HTTP response, we can use:
ResponseEntity<Product> response =
restTemplate.getForEntity(
url,
Product.class
);
Then:
HttpStatus status = response.getStatusCode();
Product product = response.getBody();
The difference is:
getForObject()
↓
Response Body
getForEntity()
↓
Status + Headers + Body
This distinction is covered in the source’s RestTemplate method table.
13. POST Request
For creating a new resource, we can use postForObject().
Product newProduct =
new Product("Ice-cream", 100);
Product createdProduct =
restTemplate.postForObject(
url,
newProduct,
Product.class
);
This sends the POST request and returns the response body.
The source also shows postForEntity() when the complete ResponseEntity is required.
14. POST Using postForEntity()
Product newProduct =
new Product("Ice-cream", 100);
ResponseEntity<Product> response =
restTemplate.postForEntity(
url,
newProduct,
Product.class
);
Product createdProduct = response.getBody();
HttpStatus status = response.getStatusCode();
Use this when you need information such as:
- HTTP status
- Headers
- Response body
15. PUT Request
For updating an existing resource:
Product updatedProduct =
new Product("Ice-cream", 150);
restTemplate.put(
url,
updatedProduct
);
The put() method is intended for a PUT request where a response body is not expected.
16. DELETE Request
For deleting a resource:
restTemplate.delete(url);
Example:
String url =
"http://localhost:8080/api/products/1";
restTemplate.delete(url);
The source describes delete() as sending a DELETE request where no response body is expected.
17. Using exchange() for More Control
Sometimes the simple methods aren’t enough.
For example, we may need to customize:
- HTTP method
- HTTP headers
- Request body
In such cases, exchange() is useful.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(
MediaType.APPLICATION_JSON
);
headers.set(
"Authorization",
"Bearer my-token"
);
Product product = new Product();
product.setName("Ice-cream");
product.setPrice(100);
HttpEntity<Product> requestEntity =
new HttpEntity<>(product, headers);
ResponseEntity<Product> response =
restTemplate.exchange(
url,
HttpMethod.POST,
requestEntity,
Product.class
);
Product result = response.getBody();
HttpStatus status = response.getStatusCode();
The uploaded notes use exchange() specifically to demonstrate customization of headers and the request body while retaining Spring’s automatic conversion capabilities.
18. execute() Method
When we need more control over the request and response processing, RestTemplate also provides:
execute()
Its structure is:
execute(
String url,
HttpMethod method,
RequestCallback requestCallback,
ResponseExtractor<T> responseExtractor
)
This provides lower-level control over request and response handling.
RequestCallback
RequestCallback allows us to customize the outgoing request.
For example:
RequestCallback requestCallback = request -> {
request.getHeaders().setContentType(
MediaType.APPLICATION_JSON
);
Product product =
new Product("Ice-cream", 100);
ObjectMapper mapper = new ObjectMapper();
byte[] body =
mapper.writeValueAsBytes(product);
StreamUtils.copy(
body,
request.getBody()
);
};
The source explains that RequestCallback provides control over the request, including headers and request body.
ResponseExtractor
ResponseExtractor controls how the response is read and converted.
Example:
ResponseExtractor<String> responseExtractor =
response -> {
return StreamUtils.copyToString(
response.getBody(),
StandardCharsets.UTF_8
);
};
Then:
String response = restTemplate.execute(
url,
HttpMethod.POST,
requestCallback,
responseExtractor
);
The source demonstrates ResponseExtractor for controlling response processing.
19. RestTemplate Method Cheat Sheet
| HTTP Operation | RestTemplate Method | Purpose |
|---|---|---|
| GET | getForObject() |
Get response body |
| GET | getForEntity() |
Get status, headers and body |
| POST | postForObject() |
POST and get response body |
| POST | postForEntity() |
POST and get complete response |
| PUT | put() |
Send PUT request |
| DELETE | delete() |
Send DELETE request |
| Any HTTP method | exchange() |
Customize method, headers and body |
| Advanced | execute() |
More control over request/response |
These methods and their intended use are summarized in the uploaded material.
20. Limitations of RestTemplate
Although RestTemplate is easy to use, it has some limitations.
1. Many overloaded methods
RestTemplate provides many methods and overloads, which can make the API harder to remember and maintain as requirements become more complex.
2. Older API design
RestTemplate comes from an older style of Spring HTTP client API, and modern requirements can require additional configuration or supporting components.
3. Maintenance mode
The source notes that RestTemplate is in maintenance mode, meaning development is focused on maintenance rather than introducing new features.
21. RestClient – The Modern Alternative
Modern Spring applications can also use RestClient, which provides a more fluent, builder-style API.
Instead of a large collection of overloaded methods, the API is designed around a more readable request-building style.
The uploaded notes highlight:
- Fluent/builder-style API
- More readable endpoint invocation
- Easier integration with interceptors and filters
So, when starting a new Spring application, it is worth understanding both RestTemplate and RestClient, particularly if you are maintaining existing applications that already use RestTemplate.
22. RestTemplate vs RestClient
| Feature | RestTemplate | RestClient |
|---|---|---|
| Communication | Synchronous | Synchronous |
| API style | Traditional | Fluent |
| Common in legacy applications | Yes | Less likely |
| Readability | Method-based | Builder-style |
| Existing project support | Very common | Increasingly relevant |
| Maintenance status | Maintenance mode | Modern Spring API |
23. Complete Microservice Flow
Putting everything together:
HTTP GET
OrderService ------------------> ProductService
| |
| |
| Process Request
| |
|<-------------------------------|
Response
The OrderService doesn’t directly access the Product Service’s database.
Instead:
OrderService
|
| REST API
↓
ProductService
|
↓
Product Database
This keeps the services separated and allows each service to expose its own API.
24. Final Takeaway
RestTemplate makes synchronous REST communication significantly simpler than directly working with low-level Java HTTP APIs.
With RestTemplate, we can easily perform:
GET
POST
PUT
DELETE
and use more flexible methods such as:
exchange()
execute()
For example:
String response = restTemplate.getForObject(
"http://localhost:8082/products/101",
String.class
);
is considerably simpler than manually managing HttpURLConnection.
However, for new Spring applications, developers should also understand the modern RestClient API, while RestTemplate remains important knowledge for maintaining existing Spring Boot applications.
Frequently Asked Questions
Is RestTemplate synchronous?
Yes. RestTemplate is used for synchronous HTTP communication, meaning the calling operation waits for the response.
Is RestTemplate still used?
Yes. It is still encountered frequently in existing Spring applications, although Spring’s newer RestClient API should also be considered for modern applications.
What is the difference between getForObject() and getForEntity()?
getForObject() returns the response body, while getForEntity() returns a ResponseEntity containing information such as the response status, headers and body.
When should I use exchange()?
Use exchange() when you need more control over the HTTP method, headers, request body and response type.
What is execute() used for?
execute() is useful when you need greater control over how the request is created and how the response is extracted.
Suggested SEO title
RestTemplate in Spring Boot: Complete Guide to Synchronous Microservice Communication
Suggested URL slug
/resttemplate-spring-boot-microservices/
Suggested meta description
Learn how to use RestTemplate in Spring Boot for synchronous microservice communication, including GET, POST, PUT, DELETE, exchange(), execute(), timeouts, and RestClient.
Suggested tags
Java, Spring Boot, RestTemplate, Microservices, REST API, Spring Framework, Java Microservices, RestClient, Backend Development