RestTemplate in Spring Boot – Synchronous Communication Between Microservices
Learn how RestTemplate can be used for synchronous communication between Spring Boot microservices. This guide covers OrderService and ProductService, HTTP communication, RestTemplate configuration, common methods, practical examples and limitations.
RestTemplate
Synchronous Communication
Learn how one microservice can communicate with another microservice using HTTP and RestTemplate.
What You'll Learn
- 1. Introduction
- 2. Setting Up Two Microservices
- 3. What is Synchronous Communication?
- 4. HTTP Request and Response
- 5. Calling REST API Using Plain Java
- 6. RestTemplate
- 7. RestTemplate Configuration
- 8. GET Request Example
- 9. RestTemplate Methods
- 10. exchange() Method
- 11. execute() Method
- 12. Common Mistakes
- 13. Best Practices
- 14. Interview Questions
- 15. PDF Notes
- 16. Frequently Asked Questions
- 17. Conclusion
- 18. Related Articles
1. Introduction
In a microservices architecture, one service often needs to communicate with another service. One approach is synchronous communication, where the client waits for the server response before continuing.
The reference material demonstrates this using an OrderService and a ProductService running on different ports. :contentReference[oaicite:4]{index=4}
2. Setting Up Two Microservices
The example uses two Spring Boot microservices:
- OrderService — client service
- ProductService — target service
The two services run on different port numbers. OrderService makes a request to ProductService.
server.port=8081
server.port=8082
3. What is Synchronous Communication?
In synchronous communication, the client waits for the server response before continuing. The communication is blocking in nature because the calling thread waits for the response.
Synchronous Communication Types in Spring Boot
- RestTemplate
- RestClient
- FeignClient
These synchronous communication options are listed in the supplied reference material. :contentReference[oaicite:5]{index=5}
4. HTTP Request and Response
Before using RestTemplate, it is useful to understand the basic HTTP request and response flow.
Example HTTP GET Request
GET /orders/1 HTTP/1.1
Host: localhost:8081
Accept: application/json
Example HTTP POST Request
POST /products HTTP/1.1
Host: localhost:8081
Content-Type: application/json
Accept: application/json
{
"name": "Ice-Cream",
"price": 100
}
Keep-Alive
The reference document explains that HTTP/1.1 uses persistent connections by default, while HTTP/1.0 defaults to closing the connection. It also discusses idle timeout and maximum request settings for keep-alive connections. :contentReference[oaicite:6]{index=6}
5. Calling REST API Using Plain Java
A REST endpoint can be called using Java's HttpURLConnection directly. However, this requires considerably more low-level request and connection handling.
@RestController
@RequestMapping("/orders")
public class OrderController {
@GetMapping("/{id}")
public ResponseEntity<String> getOrder(
@PathVariable String id) {
HttpURLConnection connection = null;
try {
String url =
"http://localhost:8082/products/" + id;
URL obj = new URL(url);
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();
return ResponseEntity.ok(
response.toString()
);
} catch (Exception e) {
return ResponseEntity
.internalServerError()
.body("Error");
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}
Problems With the Low-Level Approach
- More boilerplate code
- Manual request and response handling
- Manual connection handling
- Manual response processing
- Limited convenience for higher-level REST operations
6. What is RestTemplate?
RestTemplate provides a higher-level abstraction for calling REST APIs from Spring applications. Instead of directly creating and managing HttpURLConnection objects, the developer can use methods such as getForObject(), getForEntity(), postForObject(), put() and delete().
The supplied reference describes RestTemplate as a traditional or legacy way to call REST APIs in a Spring application. :contentReference[oaicite:7]{index=7}
7. RestTemplate Configuration
A RestTemplate instance can be exposed as a Spring bean.
@Configuration
public class AppConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
Configuring Timeouts
@Configuration
public class AppConfig {
@Bean
public RestTemplate restTemplate() {
SimpleClientHttpRequestFactory factory =
new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(1000);
factory.setReadTimeout(5000);
return new RestTemplate(factory);
}
}
The reference material demonstrates configuring connection and read timeouts using SimpleClientHttpRequestFactory. :contentReference[oaicite:8]{index=8}
8. GET Request Using RestTemplate
The getForObject() method can be used when the application needs the response body as an object.
@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 supplied PDF demonstrates this same OrderService → ProductService flow using getForObject(). :contentReference[oaicite:9]{index=9}
9. Common RestTemplate Methods
| Method | Purpose | Example |
|---|---|---|
| getForObject() | Returns the response body as an object. | restTemplate.getForObject(...) |
| getForEntity() | Returns a ResponseEntity containing response body, status and headers. | restTemplate.getForEntity(...) |
| postForObject() | Sends POST and returns the response body. | restTemplate.postForObject(...) |
| postForEntity() | Sends POST and returns ResponseEntity. | restTemplate.postForEntity(...) |
| put() | Sends a PUT request. | restTemplate.put(...) |
| delete() | Sends a DELETE request. | restTemplate.delete(...) |
| exchange() | Allows customization of HTTP method, headers and request body. | restTemplate.exchange(...) |
| execute() | Provides lower-level control over request and response processing. | restTemplate.execute(...) |
The method descriptions above follow the methods documented in the supplied reference PDF. :contentReference[oaicite:10]{index=10} :contentReference[oaicite:11]{index=11}
10. Using exchange()
The exchange() method is useful when you need more control over the HTTP method, headers and request body while still using Spring's automatic conversion.
String url =
"http://localhost:8080/api/products";
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 supplied material demonstrates exchange() for customizing headers and the HTTP request body. :contentReference[oaicite:12]{index=12} :contentReference[oaicite:13]{index=13}
11. Using execute()
When more direct control is required, RestTemplate's execute() method can work with RequestCallback and ResponseExtractor.
RestTemplate restTemplate =
new RestTemplate();
String url =
"http://localhost:8080/api/products";
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()
);
};
ResponseExtractor<String>
responseExtractor =
response -> {
return StreamUtils.copyToString(
response.getBody(),
StandardCharsets.UTF_8
);
};
String response =
restTemplate.execute(
url,
HttpMethod.POST,
requestCallback,
responseExtractor
);
System.out.println(
"response is: " + response
);
The reference material explains that RequestCallback provides control over the outgoing request and ResponseExtractor controls how the response is read and converted. :contentReference[oaicite:14]{index=14}
12. Common Mistakes
Things to Check
- Using the wrong ProductService port
- Incorrect endpoint URL
- Missing HTTP method
- Incorrect request or response type
- Missing request headers
- Not configuring suitable connection/read timeouts
- Handling errors without considering HTTP status
13. Best Practices
Recommended Practices
- Configure appropriate connection and read timeouts.
- Keep service URLs configurable rather than hard-coding them throughout the application.
- Use appropriate request and response types.
- Handle unsuccessful HTTP responses explicitly.
- Use centralized configuration where appropriate.
- Consider the communication pattern and requirements of the application before selecting a REST client.
14. RestTemplate Interview Questions
15. RestTemplate PDF Notes
Preview the first two pages of the RestTemplate notes below. The remaining pages are locked. Watch the Chai With Code video to unlock the complete PDF.
Remaining Pages Are Locked
Watch the Chai With Code video and return to this article to unlock the remaining RestTemplate PDF pages.
Complete RestTemplate PDF
Download the complete RestTemplate notes for offline reading and interview preparation.
Preparing your PDF...
16. Frequently Asked Questions
17. Conclusion
RestTemplate provides a convenient abstraction for synchronous HTTP communication from Spring applications. It can handle common operations such as GET, POST, PUT and DELETE and also provides more customizable methods such as exchange() and execute().
The supplied reference demonstrates the progression from low-level HttpURLConnection communication to RestTemplate-based communication between OrderService and ProductService. :contentReference[oaicite:16]{index=16} :contentReference[oaicite:17]{index=17}
The reference also discusses limitations of RestTemplate and introduces RestClient as a newer fluent-style API. :contentReference[oaicite:18]{index=18}