Microservice Service Splitting Principles and Remote Call Implementation with Spring Boot
This article explains microservice service‑splitting guidelines, demonstrates a small demo project with separate order‑service and user‑service modules, shows how to define independent databases, and provides step‑by‑step code for registering a RestTemplate bean and performing remote calls between services using Spring Boot.
In any distributed architecture, services must be split and refined; the same applies to microservices. This guide introduces the principles of service splitting and illustrates them with a simple demo consisting of order-service and user-service modules.
1 Service Splitting
1.1 Service Splitting Principles
Different microservices should avoid overlapping business logic to ensure low coupling.
Each microservice should own an independent database.
Microservices communicate via exposed business APIs.
The demo project structure includes:
order-service : handles order queries.
user-service : handles user queries.
1.2 Service Splitting Example
1.2.1 Demo Structure
The parent project cloud-demo contains the two services. Each service has its own database tables, e.g., cloud-order and cloud-user , with a shared id field for linking.
1.2.2 Database Table Structure
Order table stores order data; user table stores user data. The order entity will later be enriched with user information obtained via remote calls.
2 Remote Call
2.1 Remote Call Example
The order service needs to call the user service to fetch user details for an order. The required HTTP endpoint is http://localhost:8081/user/{userId} .
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RestTemplate restTemplate;
public Order queryOrderById(Long orderId) {
// 1. Query order
Order order = orderMapper.findById(orderId);
// 2. Query user via remote call
String url = "http://userservice/user/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);
// 3. Set user into order
order.setUser(user);
// 4. Return enriched order
return order;
}
}2.2 Implementation Steps
Register a RestTemplate bean in the order service's Spring Boot application class and annotate it with @LoadBalanced for load balancing.
Inject the RestTemplate into OrderService and use restTemplate.getForObject(url, User.class) to fetch user data.
Combine the retrieved User object with the Order object and return it.
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
/**
* Create RestTemplate for load balancing
*/
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}2.3 Service Provider and Consumer
In this demo, order-service acts as the consumer (caller) and user-service as the provider (callee). The roles can reverse in different business scenarios, so each service should be designed to be both provider and consumer when needed.
By following these principles and steps, developers can achieve clean service boundaries, independent data stores, and reliable remote communication in a microservice architecture.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
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.