Service-to-service communication lets different parts of an app talk to each other. This helps them work together smoothly.
When one microservice needs data from another microservice.
When you want to split a big app into smaller, focused services.
When services need to share updates or trigger actions in each other.
When building scalable apps that can grow by adding more services.
Syntax
Spring Boot
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject("http://service-url/api/data", String.class);
RestTemplate is a simple way to call other services using HTTP.
Spring Boot also supports WebClient for reactive calls.
Examples
Calls another service at localhost on port 8081 and gets a message as a string.
Spring Boot
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject("http://localhost:8081/api/message", String.class);
Uses WebClient for a blocking call to get a message from another service.
Spring Boot
WebClient webClient = WebClient.create("http://localhost:8081");
String result = webClient.get().uri("/api/message").retrieve().bodyToMono(String.class).block();
Sample Program
This Spring Boot app has two controllers. One acts as a service returning a message. The other calls that service using RestTemplate and returns the message it got.
Spring Boot
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@RestController
class ClientController {
private final RestTemplate restTemplate = new RestTemplate();
@GetMapping("/call-service")
public String callService() {
String url = "http://localhost:8081/api/message";
return restTemplate.getForObject(url, String.class);
}
}
@RestController
class ServiceController {
@GetMapping("/api/message")
public String getMessage() {
return"Hello from Service!";
}
}
OutputSuccess
Important Notes
Make sure the service you call is running and accessible at the URL you use.
Use environment variables or config files to store service URLs, not hard-coded strings.
For better performance and features, consider using WebClient instead of RestTemplate in new projects.
Summary
Service-to-service communication helps microservices work together.
RestTemplate and WebClient are common ways to call other services in Spring Boot.
Always handle errors and timeouts when calling other services.
Practice
(1/5)
1. What is the main purpose of service-to-service communication in Spring Boot microservices?
easy
A. To create user interfaces for microservices
B. To allow different microservices to exchange data and work together
C. To store data in a database
D. To compile Java code faster
Solution
Step 1: Understand microservices architecture
Microservices are small services that work independently but often need to share data or trigger actions in other services.
Step 2: Identify the role of service-to-service communication
This communication allows microservices to interact and cooperate by exchanging data or requests.
Final Answer:
To allow different microservices to exchange data and work together -> Option B
Quick Check:
Service communication = microservices working together [OK]
Hint: Microservices talk to each other to share data [OK]
Common Mistakes:
Confusing service communication with UI creation
Thinking it manages database storage
Assuming it speeds up code compilation
2. Which of the following is the correct way to create a RestTemplate bean in Spring Boot for service-to-service calls?
easy
A. @Component
public void restTemplate() {
return new RestTemplate();
}
B. @Service
public RestTemplate restTemplate() {
return new RestTemplate();
}
C. @Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
D. RestTemplate restTemplate = new RestTemplate();
Solution
Step 1: Understand Spring bean creation
To create a reusable RestTemplate, define a method annotated with @Bean inside a @Configuration class.
Step 2: Check the correct syntax
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
} correctly uses @Bean and returns a new RestTemplate instance.
Final Answer:
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
} -> Option C
Quick Check:
@Bean method returns RestTemplate instance [OK]
Hint: Use @Bean to create reusable RestTemplate [OK]
Common Mistakes:
Using @Service instead of @Bean
Not returning RestTemplate instance
Missing @Bean annotation
3. Given the following Spring Boot code snippet using WebClient, what will be the output if the called service returns "Hello from Service B"?
Hint: Always define RestTemplate as a @Bean before autowiring [OK]
Common Mistakes:
Forgetting to create RestTemplate bean
Using incomplete URL
Misunderstanding getForEntity method
5. You want to call Service D from Service E using WebClient with a timeout of 2 seconds and handle errors gracefully. Which code snippet correctly implements this?
hard
A. WebClient client = WebClient.create("http://service-d/api");
String result = client.get()
.retrieve()
.bodyToMono(String.class)
.timeout(Duration.ofSeconds(2))
.onErrorReturn("Timeout or error")
.block();
B. WebClient client = WebClient.create();
String result = client.get()
.uri("http://service-d/api")
.retrieve()
.bodyToMono(String.class)
.block(Duration.ofSeconds(2));
C. RestTemplate restTemplate = new RestTemplate();
restTemplate.setTimeout(2000);
String result = restTemplate.getForObject("http://service-d/api", String.class);
D. WebClient client = WebClient.builder()
.baseUrl("http://service-d/api")
.build();
String result = client.get()
.retrieve()
.bodyToMono(String.class)
.block();
Solution
Step 1: Setup WebClient with timeout and error handling
WebClient client = WebClient.create("http://service-d/api");
String result = client.get()
.retrieve()
.bodyToMono(String.class)
.timeout(Duration.ofSeconds(2))
.onErrorReturn("Timeout or error")
.block(); uses timeout(Duration.ofSeconds(2)) to limit wait time and onErrorReturn to provide fallback on errors.
Step 2: Verify other options
WebClient client = WebClient.create();
String result = client.get()
.uri("http://service-d/api")
.retrieve()
.bodyToMono(String.class)
.block(Duration.ofSeconds(2)); but uses block(Duration) which times out and throws an exception instead of providing a fallback; RestTemplate restTemplate = new RestTemplate();
restTemplate.setTimeout(2000);
String result = restTemplate.getForObject("http://service-d/api", String.class); tries to set timeout on RestTemplate incorrectly; WebClient client = WebClient.builder()
.baseUrl("http://service-d/api")
.build();
String result = client.get()
.retrieve()
.bodyToMono(String.class)
.block(); lacks timeout and error handling.
Final Answer:
WebClient client = WebClient.create("http://service-d/api");
String result = client.get()
.retrieve()
.bodyToMono(String.class)
.timeout(Duration.ofSeconds(2))
.onErrorReturn("Timeout or error")
.block(); -> Option A