대다수의 경우에서 DTO를 효율적으로 관리하기 위해 Inner Class로 관리하는 것을 확인할 수 있음.
관련있는 DTO끼리 묶어 상위 DTO (~DTO)로 만들고, 중복되는 필드들을 공통 클래스로 관리하면 코드 양이 줄지 않을까?
예를들어 UserDTO 가 있다면
public class UserDTO {
public static class LoginRequest {
private String username;
private String password;
}
public static class LoginResponse {
private String username;
private String password;
}
public static class DetailInfoResponse {
private Long id;
private String username;
private String role;
}
public staic class DetailInfoListResponse {
private int totalCount;
private List<DetailInfoResponse> detailInfoList;
}
}
이런식으로 표현할 수 있지 않을까?
DetailInfoListResponse
를 보면 DetailInfoResponse를 사용해 DetailInfo의 목록을 반환하는데, 이런식으로 관리하면 유지보수가 용이하지 않을까?
관련 DTO들끼리 필드를 재사용 할 가능성이 높을 것 같기 때문에 괜찮은 방법 같음.
실제 사용 예시:
/* ReviewDTO */
public class ReviewDTO {
@Getter
@Setter
/* Review Create할 때 쓸 DTO => ReviewDTO.Create */
public static class Create {
private Long tutoringId;
private String body;
private Long tagId;
}
@Getter
@Setter
/* Review Update할 때 쓸 DTO => ReviewDTO.Update */
public static class Update {
private String body;
private Long tagId;
}
@Getter
@Setter
/* Review Check할 때 쓸 DTO => ReviewDTO.Check */
public static class Check {
private Boolean isCompleted;
}
@Getter
@Setter
/* Review 반환할 때 쓸 DTO => ReviewDTO.Response */
public static class Response {
private Long id;
private String body;
private Boolean isCompleted;
private ReviewNoteDTO note;
private ReviewTagDTO tag;
/* Entity -> DTO Response */
public Response(Review review) {
this.id = review.getId();
this.body = review.getBody();
this.isCompleted = review.getIsCompleted();
this.note = new ReviewNoteDTO(review.getNote());
this.tag = new ReviewTagDTO(review.getTag());
}
/* Entity List -> DTO Response List */
public static List<Response> ResponseList (List<Review> reviewList) {
List<Response> responseList = reviewList.stream()
.map(o->new Response(o))
.collect(Collectors.toList());
return responseList;
}
@Getter
public static class ReviewNoteDTO {
private Long id;
public ReviewNoteDTO(Note note) {
this.id = note.getId();
}
}
@Getter
public static class ReviewTagDTO {
private Long id;
private String name;
public ReviewTagDTO(Tag tag) {
this.id = tag.getId();
this.name = tag.getName();
}
}
}
}
/* service 예시 */
public String createReview(ReviewDTO.Create createReview) {
Optional<Tutoring> tutoring = tutoringRepository.findById(createReview.getTutoringId());
Optional<Tag> tag = tagRepository.findById(createReview.getTagId());
// ...생략...
}
public List<ReviewDTO.Response> reviewList() {
List<Review> reviewList = reviewRepository.findAll();
return ReviewDTO.Response.ResponseList(reviewList);
}
그리고 MapStruct를 통해서 DTO와 Entity간 변환을 좀 우아하게 할 수 있는거 같은데
어려워 보여서 공부가 필요해 보임.