@PostMapping
public ResponseEntity<Long> create(@RequestBody PostRequest postRequest) {
return ResponseEntity.ok().body(postService.create(PostRequest.toEntity()));
}
@GetMapping("/{postId}")
public ResponseEntity<PostResponse> getPost(@PathVariable Long postId) {
Post post = postService.getPost(postId);
return ResponseEntity.ok().body(PostResponse.builder().post(post).build());
}
장점
Presentation Logic 분리
: DTO는 주로 클라이언트에게 데이터를 전달하기 용도로, 컨트롤러에서 DTO와의 변환 작업을 수행하면 Presentaion Logic을 컨트롤러 내부로 격리시킬 수 있다.Controller 레벨에서 유효성 검사
: DTO 변환 작업을 수행하면, 변환 과정에서 더욱 엄격한 데이터 유효성 검사를 할 수 있다.Service의 독립성 유지
: Service Layer에서 Entity에만 의존하고 응답 DTO 변환 작업을 수행하지 않으면 Service Layer의 독립성과 재사용성이 높아진다.단점
반복적인 작업
: DTO와 Entity간의 변환 작업은 여러 컨트롤러 메서드에서 반복적으로 수행되어 코드 중복이 발생비즈니스 로직과 혼재
: DTO와의 변환 작업을 Controller에서 수행하면, 비즈니스 로직과 DTO 변환 로직이 혼재되어 코드의 가독성과 유지보수성이 저하@PostMapping
public ResponseEntity<Long> create(@RequestBody PostRequest PostRequest) {
return ResponseEntity.ok().body(postService.create(PostRequest));
}
@GetMapping("/{postId}")
public ResponseEntity<PostResponse> getPost(@PathVariable Long postId) {
return ResponseEntity.ok().body(postService.getPost(postId));
}
장점
단일 장소에서의 변환 작업 관리
: 서비스는 비즈니스 로직을 관리하는 곳이므로, 변환 작업을 서비스 내에서 수행하면 변환 작업을 단일한 장소에서 관리할 수 있다.코드 중복 감소
: 서비스 내에서 변환 작업을 수행하면, 여러 컨트롤러 메서드에서 동일한 변환 작업을 반복할 필요가 없어진다.비즈니스 로직과 분리
: DTO와의 변환 작업을 서비스에서 수행하면, 비즈니스 로직과 변환 로직을 분리하여 코드를 관리할 수 있다.단점
Service의 복잡도 증가
: 변환 작업까지 포함되면 역할이 복잡해질 수 있다.코드 재사용성 하락
: 서비스에서 특정 DTO에 의존하게 되면 여러 종류의 컨트롤러에서 해당 서비스를 이용할 수 없어 코드 재사용성이 떨어지게 된다. (독립성이 떨어진다)프로젝트의 구조와 성격에 따라 선택하기
하지만, 일반적으로 서비스에서 변환 작업을 수행하는 것이 다음과 같은 이점이 있다.
레이어 간의 역할 분리
: Bussiness Logic과 Presentation Logic을 분리하여 Controller와 Service간의 역할을 명확히 구분한다.단일 책임 원칙
: Service는 주로 비즈니스 로직을 처리하는 컴포넌트로 간주되며, DTO와 Entity 간의 변환 작업은 비즈니스 로직과 관련이 있다. 따라서 변환 작업을 서비스에서 처리함으로써 단일 책임 원칙을 준수할 수 있다.