마이크로 서비스에서 DTO를 공유하는 방법

1. 개요

최근 몇 년 동안 마이크로 서비스가 인기를 얻고 있습니다. 마이크로 서비스의 필수 특성 중 하나는 모듈 식이고 격리되어 있으며 확장하기 쉽다는 것입니다. 마이크로 서비스는 함께 작동하고 데이터를 교환해야합니다. 이를 위해 DTO라는 공유 데이터 전송 개체를 만듭니다.

이 기사에서는 마이크로 서비스간에 DTO를 공유하는 방법을 설명합니다.

2. 도메인 개체를 DTO로 노출

애플리케이션 도메인을 나타내는 모델은 마이크로 서비스를 사용하여 관리됩니다. 도메인 모델은 다른 관심사이며 DAO 계층의 데이터 모델과 분리됩니다.

그 주된 이유는 클라이언트에게 서비스를 통해 도메인의 복잡성을 노출하고 싶지 않기 때문입니다. 대신 REST API를 통해 애플리케이션 클라이언트에 서비스를 제공하는 서비스간에 DTO를 노출 합니다. DTO가 이러한 서비스간에 전달되는 동안 도메인 개체로 변환됩니다 .

위의 서비스 지향 아키텍처는 도메인 개체에 대한 DTO의 구성 요소와 흐름을 개략적으로 보여줍니다.

3. 마이크로 서비스 간 DTO 공유

예를 들어 고객이 제품을 주문하는 과정을 살펴 보겠습니다. 이 프로세스는 고객 주문 모델을 기반으로합니다 . 서비스 아키텍처 측면에서 프로세스를 살펴 보겠습니다.

고객 서비스가 다음과 같이 주문 서비스에 요청 데이터를 전송한다고 가정 해 보겠습니다.

"order": { "customerId": 1, "itemId": "A152" }

고객 및 주문 서비스는 계약을 사용하여 서로 통신 합니다. 그렇지 않으면 서비스 요청 인 계약은 JSON 형식으로 표시됩니다. Java 모델로서 OrderDTO 클래스는 고객 서비스와 주문 서비스 간의 계약을 나타냅니다.

public class OrderDTO { private int customerId; private String itemId; // constructor, getters, setters }

3.1. 클라이언트 모듈 (라이브러리)을 사용하여 DTO 공유

마이크로 서비스는 요청을 처리하기 위해 다른 서비스의 특정 정보가 필요합니다. 주문 결제 요청을받는 세 번째 마이크로 서비스가 있다고 가정 해 보겠습니다. 주문 서비스와 달리이 서비스에는 다른 고객 정보가 필요합니다.

public class CustomerDTO { private String firstName; private String lastName; private String cardNumber; // constructor, getters, setters }

배송 서비스도 추가하면 고객 정보는 다음과 같습니다.

public class CustomerDTO { private String firstName; private String lastName; private String homeAddress; private String contactNumber; // constructor, getters, setters }

따라서 공유 모듈에 CustomerDTO 클래스를 배치하면 더 이상 의도 한 용도로 사용되지 않습니다. 이를 해결하기 위해 우리는 다른 방법에 접근합니다.

각 마이크로 서비스 모듈 내에서 클라이언트 모듈 (라이브러리)을 만들고 그 옆에 서버 모듈을 만들어 보겠습니다 .

order-service |__ order-client |__ order-server

위해 클라이언트 모듈은 고객 서비스와 공유 DTO가 포함되어 있습니다. 따라서 주문 클라이언트 모듈의 구조는 다음과 같습니다.

order-service └──order-client OrderClient.java OrderClientImpl.java OrderDTO.java 

OrderClient가이 정의하는 인터페이스 오더 의 주문 요청을 처리하는 방법 :

public interface OrderClient { OrderResponse order(OrderDTO orderDTO); }

order 메소드 를 구현하기 위해 RestTemplate 객체를 사용하여 POST 요청을 Order 서비스에 보냅니다.

String serviceUrl = "//localhost:8002/order-service"; OrderResponse orderResponse = restTemplate.postForObject(serviceUrl + "/create", request, OrderResponse.class);

또한 주문 클라이언트 모듈을 사용할 수 있습니다. 이제 고객 서비스 모듈 의 종속 라이브러리가됩니다 .

[INFO] --- maven-dependency-plugin:3.1.2:list (default-cli) @ customer-service --- [INFO] The following files have been resolved: [INFO] com.baeldung.orderservice:order-client:jar:1.0-SNAPSHOT:compile

물론 이것은 주문 서버 모듈이 "/ create"서비스 엔드 포인트를 주문 클라이언트에 노출시키는 목적이 없습니다 .

@PostMapping("/create") public OrderResponse createOrder(@RequestBody OrderDTO request)

이 서비스 엔드 포인트 덕분에 고객 서비스는 주문 클라이언트를 통해 주문 요청을 보낼 수 있습니다. 클라이언트 모듈을 사용하여 마이크로 서비스는보다 격리 된 방식으로 서로 통신합니다. DTO의 속성은 클라이언트 모듈 내에서 업데이트됩니다. 따라서 계약 파기는 동일한 클라이언트 모듈을 사용하는 서비스로 제한됩니다.

4. 결론

이 기사에서는 마이크로 서비스간에 DTO 개체를 공유하는 방법을 설명했습니다. 기껏해야 마이크로 서비스 클라이언트 모듈 (라이브러리)의 일부로 특별 계약을 체결하여이를 달성합니다. 이러한 방식으로 API 리소스가 포함 된 서버 부분에서 서비스 클라이언트를 분리합니다. 결과적으로 몇 가지 이점이 있습니다 .

  • 서비스 간 DTO 코드에 중복성이 없습니다.
  • 계약 파기는 동일한 클라이언트 라이브러리를 사용하는 서비스로 제한됩니다.

Spring Boot 애플리케이션의 코드 샘플은 GitHub에서 사용할 수 있습니다.