마이크로 서비스간에 DTO 객체 공유


15

TL; DR-서비스간에 POJO 라이브러리를 공유해도 되나요?

일반적으로 우리는 가능한 경우 서비스 간 공유를 없음으로 엄격하게 제한하고 싶습니다. 데이터를 공유하는 서비스가 클라이언트가 사용할 클라이언트 라이브러리를 제공해야하는지에 대한 논쟁이있었습니다. client-lib는 일반적으로 서비스 클라이언트가 선택적으로 사용할 수 있으며 client-lib를 사용하든 대체 언어를 사용하든 라이브러리 등의 일반적인 측면을 사용하든 API를 사용할 수 있습니다.

필자의 경우-데이터 객체를 만드는 서비스라고 생각합니다. 이 개체가 PET라고 가정합니다. 데이터베이스 엔터티는 아니지만 기본 데이터를 암시 적으로 나타내는 POJO입니다. 이 POJO는 API가 정의한 것입니다. 애완 동물-연령, 체중, 이름, 소유자, 주소, 종 등

서비스 1 -PetKeeper : 어떤 이유로 든 애완 동물을 생성하고 모든 데이터를 유지하며 애완 동물을 얻거나 애완 동물을 수정하기 위해이 서비스를 참조해야합니다. 이 서비스에 대한 API 호출.

서비스 2- 애완 동물 접근 자 :이 서비스는 애완 동물을 모으고 유효성 검사를 수행합니다.

서비스 3,4- 더 많은 중간 서비스 요청

서비스 5- 사용자 인터페이스

이것들은 매우 임의적이지만 요점은 간단합니다. UI 또는 일부 사용자 대면 서비스는이 "PET"개체를 어떤 식 으로든 제시하려고합니다. 필요한 정보를 수집하고 릴레이를 시작하는 서비스에 도달 할 때까지 서비스를 호출하는 서비스를 호출하는 서비스를 API를 통해 호출해야합니다. 마지막으로 UI 서비스에는 표시 할 PET 개체가 있습니다.

이것은 매우 일반적입니다. 그러나 절대적인 사고 방식으로 모든 서비스에서 PET 개체를 복제했습니다. DRY (반복하지 마십시오) 원칙은 서비스 내부의 코드에만 적용되며 여러 서비스에 적용되지 않지만 요점은 여전히 ​​있습니다. 필드를 추가하면 ... 각각 POJO의 5 개 서비스를 수정해야합니다.

-또는-API의 일부 포조를 포함하는 Pet-Objects-Library를 제공 할 수 있으며 각 서비스는 라이브러리에서 가져 오기 / 의존성을 가질 수 있습니다. 서비스 자체에는 의존하지 않고 일반 라이브러리 만 있습니다. 각 서비스가 동일한 유형의 개체를 가지며 업데이트가 더 쉬워 지도록이 아이디어가 마음에 듭니다. 그러나 나는 하나님의 대상에 대해 걱정하고 있습니다.

프로 / 콘은 무엇입니까-최고의 디자인은 무엇입니까? 분리 된 상태를 유지하면서 동일한 POJO 클래스 반복을 최소화하기 위해 서비스간에 데이터를 전달하기 위해 무엇을 했습니까?



@ DaiKaixian : 분명히 OP가 God 객체와 함께 가야 한다고 제안 하지 않습니까? 그것은 일반적으로 반 패턴으로 간주됩니다.
Makoto

@javaguy의 답변에 동의합니다.

그리고 또한 말하고 싶습니다. visitor-pattern을 고려할 수 있습니다. en.wikipedia.org/wiki/Visitor_pattern . POJO에서 모든 필드와 setter / getter를 작성하고 마이크로 서비스간에 공유하십시오. 다른 마이크로 서비스에서 POJO에 대한 조작을 수행하려면 VisitorClass를 작성하십시오.

감사. 이 '공통 라이브러리'를 갖는 것에 대한 나의 주저는 그것이 커질 것이라는 것입니다. 그리고 그 안에는 서비스 1 & 3, 또는 2 & 4, 또는 전부 또는 이들의 조합 만 신경 쓰는 객체가있을 것입니다. Vistor 패턴을 사용하든 간단한 DTO POJO를 사용하든 그렇지 않든 모든 DTO를 포함하는 일반적인 DTO 라이브러리 패키지 유형입니다. 이 모든 대상을 포함하지만 가능한 한 최선을 유지하려고 노력할 수 있습니까? 최소한 물건을 사용하려는 경우 물건이 필요한 사람에게 제공됩니다.

답변:


5

최고의 디자인은 무엇입니까?

백엔드 서비스 (일반적인 비즈니스 로직을 처리하는)간에 동일한 Pet DTO 오브젝트를 재사용 할 수 있지만 프리젠 테이션 티어 (사용자 인터페이스)와 관련하여 일반적으로 FormBean (필드가 추가 된 다른 Bean) 을 사용하는 것이 좋습니다. 그래서) 프리젠 테이션 로직에 대한 프리젠 테이션 로직과 비즈니스 로직 사이에 명확한 분리가있을 것입니다 .

이는 서비스를 재사용 할 수 있어야하고 단일 서비스가 여러 엔드 포인트 (프론트 엔드 또는 다른 웹 서비스 등)에 의해 노출 / 재사용 될 수 있고 각 엔드 포인트에 의해 채워지는 추가 필드가 필요할 수 있기 때문에 필요합니다. 서비스 위의 해당 컨트롤러 또는 계층 (예 : 어댑터)

동일한 POJO 클래스의 반복을 최소화하면서 분리 된 상태를 유지하기 위해 서비스간에 데이터를 전달하기 위해 무엇을 했습니까?

비즈니스 계층과 웹 계층간에 단일 Bean을 사용하는 경우 프리젠 테이션 로직을 비즈니스 로직과 긴밀하게 결합하는 것이 좋습니다. 이는 우수 사례가 아니며 프론트 엔드에서 요구 사항에 대한 서비스를 변경하게됩니다 (예 : 다른 날짜 형식). 사용자 인터페이스에 표시됩니다. 또한, / 채우기 (FormBean에 또는 viceversa에에 DTO 등), 당신은 같은 라이브러리를 사용할 수있는 콩에서 데이터를 복사하는이 과정을 만들기 위해 아파치 BeanUtils.copyProperties()도저를 상용구 코드를 방지하기를 .


프리젠 테이션 레이어가 들어오는 페이로드를 필요에 따라 다른 속성을 가진 프리젠 테이션 Bean으로 직렬화 해제해야 할 것에 동의합니다. 그러나 일반적으로 모든 백엔드 서비스에서 동일한 DTO 객체를 재사용해도 괜찮습니까? 일반적으로 이러한 DTO 패키지는 필요한 몇 가지 서비스에 대해서만 더 작은 패키지로 분리하려고합니다. 모든 서비스가 의존하는 75 개 이상의 마이크로 서비스에 대한 DTO가있는 DTO 라이브러리 패키지의 쓰레기 서랍을 가지고있는 것이 지겨워 요. 처음에는 선택적인 DTO 객체이기 때문에 괜찮지 않습니까?

PetServices. 중복을 피하기 위해 같은 종류의 백엔드 서비스에서 동일한 DTO 객체를 재사용 할 수 있습니다 . 그러나 내 요점은 백엔드와 프론트 엔드를 밀접하게 결합하지 않는다는 것입니다.
개발자

4

DTO가 모든 마이크로 서비스에서 동일한 비즈니스 엔티티를 나타내는 경우 서비스간에 공유되는 클래스는 하나만 있어야합니다. 동일한 객체에 대해 중복 코드를 갖는 것은 (거의) 결코 정확하지 않습니다.


3
마이크로 서비스에서 DTO를 공유하는 것은 악몽입니다. "이 버전에 이미이 필드가 있습니까? 흠?" 당신은 잠시 후 진짜 혼란으로 끝날 것입니다. 이 경우 중복 코드가 좋습니다.
Mejmo

1

내가 지금 계획하는 방법은 각 서비스가 DTO 만 패키지하고 jar 라이브러리로 Nexus에 넣는 것입니다. 다른 서비스에 필요한 경우 DTO lib가 manve / gradle의 종속성으로 표시됩니다. 새로운 DTO 버전이 하나의 서비스로 출시되는 경우, 이전 버전도 동시에 지원되는 한도 훌륭하므로 이전 버전과의 호환성, 버전 관리 등을 중단하지 마십시오. 따라서 백엔드-백엔드 영역입니다. 또한 순환 종속성을 방지하기 위해 서비스를 dto 포장과 분리하는 것이 좋습니다.

이제 백엔드에서 프론트 엔드를 보거나 그 반대로 프리젠 테이션 레이어와 같은 UI가 다르다는 이전 의견에 동의하지 않습니다. 그것은 아니다 !!! UI는 이벤트를 소비하고 생성하는 또 다른 마이크로 서비스입니다.

백엔드에서 프론트 엔드 방향 POJO (dtos)를 Typescript 인터페이스로 변환하고 패키지를 NPM으로 변환하여 Nexus에로드하는 것입니다. 그런 다음 UI nodejs 기반 프로젝트가이를 사용하고 사용합니다. 이것은 UI에 대한 서비스입니다.

프론트 엔드에서 백엔드 방향 UI에서 서비스 계층 이벤트를 처리하기 위해 Typescript 인터페이스를 변환하고 POJO (dtos)로 변환하고 jar로 패키징하고 jar 형식으로 Nexus (또는 일부 repo)에 업로드하여 백엔드 서비스에서 사용합니다.

이러한 프로세스는 CI 프로세스 (Travis, Gitlab CI 등)로 쉽게 처리됩니다.

이 접근법에 대한 의견은 환영합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.