-
3. [TodoList] - dto 설계AppCenter/TodoList 2023. 5. 17. 22:41반응형
도메인, 서비스, 레포지토리를 설계해보았으니 이번엔 dto를 설계해보자.
dto 를 써야하는 이유
api 통신시 반환 값으로 엔티티 그대로를 반환하면 되지 왜 dto를 사용할까??
지금은 간단한 TodoList 프로젝트지만 만약 프로젝트가 매우 커져서 User 테이블에 10개 이상의 필드가 들어간다고 가정해보자.
사용자 이름과 게시한 글 수를 보여주는 화면을 출력하기 위해 데이터를 요청한 뒤 User 엔티티를 반환할 경우 전체 속성을 조회해 반환하기 때문에 요청한 화면에서는 필요없는 속성까지 넘겨주게 되는것이다.
이렇게되면 API 응답에서 필요 이상으로 많은 속성을 넘겨주기때문에 속도 또한 느려진다.
이것말고도 dto를 사용했을때 여러가지 장점에 대해 잘 정리된 포스트가 있어 아래 링크를 걸어두겠다.
https://tecoble.techcourse.co.kr/post/2020-08-31-dto-vs-entity/
요청과 응답으로 엔티티(Entity) 대신 DTO를 사용하자
…
tecoble.techcourse.co.kr
TaskRequestDto
1234567891011121314151617181920212223242526272829303132333435363738394041424344@Getter@Schema(description = "TodoRequest")public class TaskRequestDto {@Getter@Setterpublic static class TaskSaveReqDto {@Schema(example = "Todo 제목")@NotEmptyprivate String title;@Schema(example = "Todo 내용")private String contents;@NotEmpty@Schema(example = "Todo 기한")private String deadline;private boolean isCompleted;public Task changeEntity(TaskSaveReqDto TaskSaveReqDto) {return Task.builder().title(TaskSaveReqDto.title).contents(TaskSaveReqDto.contents).deadline(parseDatetime(TaskSaveReqDto.deadline)).isCompleted(TaskSaveReqDto.isCompleted).build();}}@Getter@Setter@AllArgsConstructorpublic static class TaskEditRequestDto {private String title;private String contents;private String deadline;private boolean isCompleted;}public static LocalDateTime parseDatetime(String deadline) {DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");return LocalDate.parse(deadline, dateTimeFormatter).atStartOfDay();}}cs 이전에 Service에서 만들었던 CRUD 중 Read 와 Delete는 모두 컨트롤러에서 id 값만 받아오면 가능하기 때문에 따로 RequestDto를 만들 필요가 없다.
TaskSaveRequestDto, TaskEditRequestDto 는 모두 정적 내부 클래스로 만들어 바깥 클래스에 대한 참조를 막아 메모리 누수를 방지하고, 응집도를 높혔다.
수정 시 TaskEditRequestDto를 받아와 Task 로 변환할 때 String 형식의 deadline을 LocalDateTime 형식으로 변환해줘야한다. 이 때, parseDatetime 메소드는 String 형식으로 받아온 deadline을 LocalDateTime 형식으로 변환해주는 역할을 한다.
TaskResponseDto
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566public class TaskResponseDto {@Getter@Setterpublic static class TaskSaveRespDto {@Schema(example = "Todo 제목")@NotEmptyprivate String title;@Schema(example = "Todo 내용")private String contents;@NotEmpty@Schema(example = "Todo 기한")private String deadline;private boolean isCompleted;public TaskSaveRespDto(Task task) {this.title = task.getTitle();this.contents = task.getContents();this.deadline = task.getDeadline().toString();this.isCompleted = task.getIsCompleted();}}@Getter@Setterpublic static class TaskDeleteRespDto {@Schema(example = "Todo 제목")@NotEmptyprivate String title;@Schema(example = "Todo 내용")private String contents;@NotEmpty@Schema(example = "Todo 기한")private String deadline;private boolean isCompleted;public TaskDeleteRespDto(Task task) {this.title = task.getTitle();this.contents = task.getContents();this.deadline = task.getDeadline().toString();this.isCompleted = task.getIsCompleted();}}@Getter@Setter@AllArgsConstructorpublic static class TaskEditRespDto {private String title;private String contents;private String deadline;private boolean isCompleted;public TaskEditRespDto(Task task) {this.title = task.getTitle();this.contents = task.getContents();this.deadline = task.getDeadline().toString();this.isCompleted = task.getIsCompleted();}}}cs TaskRequestDto 와 마찬가지로 정적 내부 클래스로 구현했다.
TaskRequestDto 로 받아온 정보를 Task로 변환해 데이터베이스에 저장한 뒤 TaskResponseDto로 변환하기 위해 Task 를 파라미터로 받는 생성자를 만들었다.
UserRequestDto & UserResponseDto
12345678910111213141516171819@Getterpublic class UserRequestDto {@Getter@Setterpublic static class UserJoinReqDto {private String name;private String password;private String email;public User changeEntity(UserJoinReqDto UserJoinReqDto) {return User.builder().name(UserJoinReqDto.name).password(UserJoinReqDto.password).email(UserJoinReqDto.email).build();}}}cs 12345678910111213141516public class UserResponseDto {@Getter@Setterpublic static class UserJoinRespDto {private String name;private String password;private String email;public UserJoinRespDto(User user) {this.name = user.getName();this.password = user.getPassword();this.email = user.getEmail();}}}cs 위에서 dto 에 대해 자세히 설명했기때문에 따로 설명할것이 없다.
domain, dto, service, repository를 분석했으니 다음 포스팅때는 controller에 대해 알아보자.
728x90반응형'AppCenter > TodoList' 카테고리의 다른 글
TodoList - RestControllerAdvice + ExceptionHandler를 이용한 예외처리 (0) 2023.07.11 2. [TodoList] - Service & Repository 설계 (0) 2023.05.16 1. [TodoList] - 도메인 설계 (0) 2023.05.15