물리적으로 분산된 시스템 서비스간의 통신 필수
ex) user service와 order service가 분산되어있는 경우(DB도 각각의 DB를 가짐) Client에게 주문 내역을 보여주기 위해서는 서로간의 통신이 필요!
user service에 Rest Template을 사용 해 봅시다 :)
1. Bean으로 등록
@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
2. user service에 service에 Rest Template 추가.( 빈으로 등록된 Rest Template을 주입 받는 과정 필요 - 이 과정은 생략)
order-service
@GetMapping("/{userId}/orders")
public ResponseEntity<List<ResponseOrder>>
getUsers(@PathVariable("userId")String userId){
List<OrderDto> orders = orderService.getOrdersByUserId(userId);
List<ResponseOrder> responseOrders=new ArrayList<>();
List<ResponseOrder> collect = orders.stream()
.map(o -> new ResponseOrder(o.getProductId(),
o.getUnitPrice(),
o.getTotalPrice(),
o.getStock(),
o.getCreatedAt(),
o.getOrderId()))
.collect(Collectors.toList());
return ResponseEntity.status(HttpStatus.OK).body(collect);
}
user-service
@Override
public UserDto getUserByUserId(String userId) {
UserEntity userEntity=userRepository.findByUserId(userId);
if (userEntity==null)
throw new UsernameNotFoundException("User not found");
UserDto userDto=new ModelMapper().map(userEntity,UserDto.class);
// Rest Template으로 order-service에다 요청을 보내는 과정
String orderUrl="http://127.0.0.1:8000/order-service/%s/orders";
ResponseEntity<List<ResponseOrder>>
orderListResponse = restTemplate.exchange(orderUrl,
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<ResponseOrder>>(){
});
List<ResponseOrder> orderList = orderListResponse.getBody();
userDto.setOrders(orderList);
return userDto;
}
Rest Template을 활용하여 user-service에서 order-service에 요청을 보내고 응답을 받는 모습을 보여주고 있음.
3. Re Factoring
2번에서의 user-service의 코드를 보면 코드에서 직접 URL에 요청을 보내고 있는 모습을 볼 수 있습니다. 만약 요청하고자 하는 URL의 IP가 변경되거나 Port가 변경되는 등 변경 사항이 생기게 되면 코드를 다시 고쳐야하는 번거로운 작업이 필요할 수 있습니다. 따라서, Configuration 정보에 요청하고자 하는 service에 URL을 저장해놓고 사용하는 것이 바람직 합니다. 이를 위해서는 Environment 객체를 주입 받아서 사용 하여야 합니다. (주입하는 과정은 생략)
Configuration 파일에
order_service:
url: http://127.0.0.1:8000/order-service/%s/orders
이와 같이 명시 해 놓으면 됩니다!
user-service
@Override
public UserDto getUserByUserId(String userId) {
UserEntity userEntity=userRepository.findByUserId(userId);
if (userEntity==null)
throw new UsernameNotFoundException("User not found");
UserDto userDto=new ModelMapper().map(userEntity,UserDto.class);
// Rest Template으로 order-service에다 요청을 보내는 과정
//String orderUrl="http://127.0.0.1:8000/order-service/%s/orders";
String orderUrl=String.format(env.getProperty("order_service.url")
,userId);
ResponseEntity<List<ResponseOrder>>
orderListResponse = restTemplate.exchange(orderUrl,
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<ResponseOrder>>(){
});
List<ResponseOrder> orderList = orderListResponse.getBody();
userDto.setOrders(orderList);
return userDto;
}
이 글은 인프런 이도원님의 'Spring Cloud로 개발하는 마이크로서비스 애플리케이션'을 수강하고 작성합니다.
출처:https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4/dashboard