REST API - DTO 여부
저는 현재 프로젝트의 REST-API를 만들고 있으며, 베스트 프랙티스에 관한 기사를 읽고 있습니다.많은 사람들이 DTO에 반대하며 도메인 모델만 노출하는 것처럼 보이는 반면, 다른 사람들은 DTO(또는 사용자 모델 또는 당신이 부르고 싶은 모든 것)가 나쁜 관행이라고 생각하는 것처럼 보입니다.개인적으로 나는 이 기사가 매우 타당하다고 생각했다.
그러나 추가 매핑 코드, DTO 카운터 파트와 100% 동일한 도메인 모델 등의 DTO의 단점도 이해했습니다.
API는 대부분 다른 클라이언트가 데이터를 소비할 수 있도록 작성되어 있습니다만, 올바르게 작성하면 가능하면 자체 웹 GUI에도 사용하고 싶습니다.
문제는 모든 도메인 데이터를 다른 클라이언트 사용자에게 노출하고 싶지 않을 수 있다는 것입니다.대부분의 데이터는 당사 자체 웹 애플리케이션에서만 의미가 있습니다.또한 모든 시나리오에서 개체에 대한 모든 데이터(특히 다른 개체와의 관계 등)를 노출하고 싶지 않을 수도 있습니다.예를 들어 특정 오브젝트의 목록을 표시할 경우 오브젝트 계층 전체를 표시할 필요는 없습니다.그러면 오브젝트의 자녀는 공개되지 않고 링크(증오)를 통해 검출될 수 있습니다.
이 문제를 어떻게 해결해야 할까요?다양한 시나리오에서 노출되는 데이터를 제어하기 위해 도메인 모델에 Jackson 믹스인을 사용할까 생각하고 있습니다.아니면 단점과 논란을 감안하더라도 DTO를 계속 사용해야 할까요?
REST API에서 DTO를 사용해야 하는 이유
DTO는 Data Transfer Object의 약자입니다.
이 패턴은 웹 서비스와 마찬가지로 리모트인터페이스로의 데이터 전송이라는 매우 명확한 목적을 가지고 작성되었습니다.이 패턴은 REST API에 매우 적합하며 DTO는 장기적으로 더 많은 유연성을 제공합니다.
어플리케이션의 도메인을 나타내는 모델과 API에서 처리되는 데이터를 나타내는 모델은 서로 다른 관심사(또는 적어도 그래야 합니다)이며 서로 분리해야 합니다.응용 프로그램 도메인 모델에서 필드를 추가, 제거 또는 이름을 변경할 때 API 클라이언트를 중단하지 않을 수 있습니다.
서비스 계층은 도메인/영속성 모델 상에서 동작하지만 API 컨트롤러는 다른 모델세트로 동작해야 합니다.예를 들어 도메인/영속성 모델이 새로운 비즈니스 요건을 지원하도록 진화함에 따라 이러한 변경을 지원하는 새로운 버전의 API 모델을 작성할 수 있습니다.또한 새로운 버전이 출시되면 이전 버전의 API를 사용하지 않는 것이 좋습니다.그리고 모든 것이 분리될 때 완벽하게 성취할 수 있습니다.
지속성 모델 대신 DTO 노출의 몇 가지 이점을 언급하면 다음과 같습니다.
지속성 모델을 API 모델에서 분리합니다.
DTO는 요구에 맞게 조정할 수 있으며 지속성 엔티티의 속성 세트만 노출하는 경우에 적합합니다.일부 속성의 직렬화를 방지하기 위해 및 같은 주석이 필요하지 않습니다.
DTO를 사용하면 지속성 엔티티에서 많은 주석을 피할 수 있습니다. 즉, 지속성 엔티티가 지속성 관련 주석으로 인해 비대해지지 않습니다.
리소스를 생성하거나 업데이트할 때 수신되는 속성을 완전히 제어할 수 있습니다.
Swagger를 사용하는 경우 및 주석을 사용하여 지속성 엔티티를 방해하지 않고 API 모델을 문서화할 수 있습니다.
API 버전별로 다른 DTO를 가질 수 있습니다.
관계를 매핑할 때 유연성이 향상됩니다.
미디어 유형에 따라 다른 DTO를 가질 수 있습니다.
DTO 에는, HATEOAS 의 링크 리스트를 설정할 수 있습니다.그것은 지속성 오브젝트에 추가되어서는 안 되는 것입니다.Spring HATEOAS 를 사용하는 경우는, DTO 클래스를 확장(이전에는 )하거나, 로 랩(이전에는 )할 수 있습니다.
보일러 플레이트 코드 취급
지속성 엔티티를 DTO에 매핑할 필요가 없으며 DTO에 매핑할 필요도 없습니다.이를 위해 사용할 수 있는 매핑 프레임워크는 여러 가지가 있습니다.예를 들어, MapStruct는 주석 기반이며 Maven Annotation Processor로 작동합니다.CDI 및 스프링 기반 응용 프로그램 모두에서 잘 작동합니다.
또한 Lombok이 getters, setters, setters를 생성하는 것도 고려할 수 있습니다.equals()
,hashcode()
그리고.toString()
방법을 찾아보세요.
관련:DTO 클래스에 이름을 붙이려면 다음 답변을 참조하십시오.
API가 공개되어 있고 여러 버전을 지원해야 하는 경우 DTO를 사용해야 합니다.
한편 개인 API로 클라이언트와 서버를 모두 제어할 수 있다면 DTO를 건너뛰고 도메인 모델을 직접 노출하는 경향이 있습니다.
나는 DTO를 사용하는 경향이 있다.
단점은 마음에 들지 않지만 다른 옵션은 더 나쁜 것 같습니다.
도메인 오브젝트를 전개하면 보안 문제나 데이터 유출이 발생할 수 있습니다.잭슨 주석으로 인해 문제가 해결된 것처럼 보일 수 있지만, 실수를 해서 노출되어서는 안 되는 데이터를 노출시키는 것은 너무 쉽습니다.DTO 클래스를 설계할 때 이러한 실수를 저지르는 것은 훨씬 어렵습니다.
한편, 오브젝트 대 오브젝트 매핑이나 Lombok 등의 보일러 플레이트를 줄일 수 있어 DTO 접근법의 단점을 줄일 수 있습니다.
이미 말씀하셨듯이, 이것은 분명히 의견과 관련된 질문입니다.저는 단순히 당신이 필요로 하는 보일러 플레이트 코드 때문에 No-DTOs 접근법에 더 끌립니다.
이는 주로 json/rest api의 응답 측에 해당됩니다.Jackson의 애드온도 작성했습니다.이러한 케이스에 대해서, 많은 json 뷰/필터를 쓰는 것을 피하기 위해서입니다.https://github.com/Antibrumm/jackson-antpathfilter
한편, DTO는 이러한 API의 요구 입력 측에 있어서 좋은 것입니다.엔티티에서 직접 작업하는 것은 예를 들어 쌍방향 관계를 고려할 때 매우 어려울 수 있습니다.또, 발신자가 「작성자」속성을 변경하는 등, 실제로는 하고 싶지 않습니다.따라서 이러한 요청을 매핑하는 동안 특정 필드를 허용하지 않아야 합니다.
언급URL : https://stackoverflow.com/questions/36174516/rest-api-dtos-or-not
'programing' 카테고리의 다른 글
OS X 10.9에 Java 설치(Mavericks) (0) | 2022.08.25 |
---|---|
Vuex 필터 상태 (0) | 2022.08.25 |
Vue.js 2: sass/scss에서 사용할 수 없는 범위 스타일 (0) | 2022.08.25 |
각 요소를 슬롯에 랩하려면 어떻게 해야 하나요? (0) | 2022.08.25 |
이.$store.dispatch().then()은 Vuex에서 작동하지 않습니다. (0) | 2022.08.25 |