지금까지는 MSA 설계를 하며 다른 서비스간의 통신이 없었습니다. 하지만 Challet Bank라는 서비스에서 다른 Bank의 계좌를 조회할 필요가 있어 MSA 통신 방법에 대해 찾아보고 적용해봤습니다.
해당 페이지는 MSA간의 통신 방법 중 RestApi 통신 방법입니다
실제로 서비스 간 통신을 하기전에, 어떤 통신 방식으로 리팩토링을 진행해야 할지 먼저 종류를 살펴봅시다.
서비스 간 통신의 종류는 크게 동기 방식과 비동기 방식으로 나뉘게 됩니다
따라서, 서비스 간 통신 방식 결정을위해서는 동기 방식으로 서비스를 호출할지 비동기 방식으로 서비스를 호출할지를 결정해야 합니다.
동기 방식은 기존 HTTP / REST 요청이 동기 방식이기 때문에 익숙한 방식이지만 다수의 요청이 들어왔을 때 지연이 길어질 수 있습니다.
하지만 비동기 방식은 여러 요청을 동시에 처리할 수 있기 때문에 지연이 적고 성능이 좋지만 이에 따라 고려할 점이 많습니다.
이러한 상황에서 저는 애플리케이션의 규모가 작기도 하고 익숙하고 비교적 쉽게 구현할 수 있는 동기 방식을 선택하였습니다.
동기 방식 중에서는 RestTemplate과 OpenFeign이 존재합니다.
옛날부터 RestTemplate을 자주 써왔지만, RestTemplate이 Deprecated까지는 아니고 maintenance mode가 됨에 따라서 사용하지 않는 것을 권장하는 것을 볼 수 있었습니다.
RESTful 웹 서비스와 통신하고 API와 상호 작용하는 편리한 방법을 제공합니다
RestTemplate을 사용하면 GET, POST, PUT, DELETE 등과 같은 다양한 HTTP 메서드를 수행하고 JSON, XML 또는 양식 인코딩 데이터와 같은 다양한 형식의 데이터를 보내고 받을 수 있습니다. 기본 HTTP 클라이언트의 복잡성을 추상화하고 웹 서비스 사용 프로세스를 단순화 할 수 있는 특징이 있습니다.
특징
Http 프로토콜을 이용해서 또 다른 서비스를 이용하는 방법
본격적으로 서비스 간 통신에 RestTemplate 을 적용해봅시다
@SpringBootApplication
public class BankServiceApplication {
public static void main(String[] args) {
SpringApplication.run(BankServiceApplication.class, args);
}
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
public class ChalletBankController {
private final ChalletBankService challetBankService;
@GetMapping("/test")
public ResponseEntity<KbTransactionDetailResponseDTO> test(){
KbTransactionDetailResponseDTO kbTransactionDetailResponseDTO = challetBankService.getTest(1L);
return ResponseEntity.status(HttpStatus.OK).body(
kbTransactionDetailResponseDTO);
}
}
@Schema(description = "거래 상세 조회 응답 DTO")
public record KbTransactionDetailResponseDTO(
@Schema(description = "거래 금액")
Long transactionAmount,
@Schema(description = "거래 일시")
LocalDateTime transactionDatetime,
@Schema(description = "입금처")
String deposit,
@Schema(description = "출금처")
String withdrawal,
@Schema(description = "거래 후 잔액")
Long transactionBalance,
@Schema(description = "카테고리", allowableValues = {"DELIVERY", "TRANSPORT", "COFFEE", "SHOPPING"})
Category category
) {
}

kb_service:
url: http://localhost:8000/api/kb-bank/details
@Service
@RequiredArgsConstructor
public class ChalletBankServiceImpl implements ChalletBankService {
private final ChalletBankRepository challetBankRepository;
private final Environment env;
private final JwtUtil jwtUtil;
private final RestTemplate restTemplate;
@Override
public KbTransactionDetailResponseDTO getTest(Long AccountId){
// URL 생성
String kbUrl = String.format(env.getProperty("kb_service.url"));
// 요청 헤더 생성
HttpHeaders headers = new HttpHeaders();
headers.add("TransactionId", String.valueOf(AccountId)); // 헤더에 Long을 String으로 변환하여 추가
// HttpEntity에 헤더 포함
HttpEntity<String> entity = new HttpEntity<>(headers);
// 요청 보내기
ResponseEntity<KbTransactionDetailResponseDTO> kbList = restTemplate.exchange(
kbUrl,
HttpMethod.GET,
entity,
new ParameterizedTypeReference<KbTransactionDetailResponseDTO>() {}
);
// 결과 받기
KbTransactionDetailResponseDTO kbTransactionDetailResponseDTOList = kbList.getBody();
return kbTransactionDetailResponseDTOList; // 실제 데이터를 반환
}
}

