쌩로그

응답 DTO에 대한 고민 본문

Project/23년 6월의 프로젝트

응답 DTO에 대한 고민

.쌩수. 2023. 7. 3. 17:53
반응형

목차

  1. 포스팅 개요
  2. 본론
  3. 요약 및 결심

1. 포스팅 개요

class Board { 
    private Long id; 
    private String title; 
    private String content; 
    private LocalDateTime createdAt; 
    private LocalDateTime modifiedAt; 
}

대략 이런 게시판 역할을 하는 Entity가 있다고 가정해보자.
(애너테이션 생략)

게시판 단일 조회시, 이 Entity의 필드들을 응답용 데이터 전송 객체(이하 ResponseDto)에 그대로 담아서 줄 수 있을 것이다.

class BoardDto { 
    public static OnethignResponseDto { 
        private Long id; 
        private String title; 
        private String content; 
        private LocalDateTime createdAt; 
        private LocalDateTime modifiedAt; 
    } 
}

이렇게 말이다..

그럼 오늘 포스팅 끝? 설마요.. 제목을 보세요;; ~

그런데, 전체 게시판 목록을 프론트에게 줄 때....
과연 저 모든 정보를 다 주는 게 좋을까...? 굳이 다 줄 필요가 있을까...?

홈페이지마다 게시판 목록을 들어가보면,
저 5개 내용 중엔 진짜 꼽아봤자 줄만한 정보는 title(게시판 제목), createdAt(생성일자) 외에는 없다.

목록에서 id는 데이터를 넘겨준다 하더라도,
목록에서 본문을 보여줄 필요가 있을까..?
혹은 수정 일자를 보여줄 필요가 있을까..?

한번 같이 생각해보면 좋겠다.

물론 백엔드 개발자로서 UI 혹은 프론트엔드 개발자의 영역을 신경쓰는 게 지금은 주제 넘는다는 생각이 들기도 한다.
(나중에 내가 발전했을 때는 또 모르지만...)

그리고 백에서 프론트에서 들어온 데이터 중 쓸데없는 데이터를 걸러낼 수 있다.
마찬가지로 프론트에서도 백에서 온 데이터 중 쓸데없는 데이터들을 거를 수 없겠는가...
당연히 되겠지...
그러면 하나의 응답 객체로 모든 정보를 줘도 될 것이다..

그런데, 어떻게 생각해도 "굳이"인 것 같다..

여튼 결론은...

"ResponseDto를 케이스 별로 여러 개를 만드는 게 과연 효율적일까...?"
혹은
"하나의 ResponseDto만 사용하면 특정 도메인에 대한 응답이 모두 같은 정보를 제공할 수 있다.
그렇게 되면 하나의 응답 DTO만 관리하므로, 유지보수에 용이하다고 하는데, 그렇다고 이게 효율적일까?"

라는 고민에서 시작된 글이다.

2. 본론

결론부터 말하면 정답은 없다.
그냥 개발자의 성향과 프로젝트의 규모, 성격 등이 결정하는 것 같다.

그리고 한 가지 말하지 않은 것이 있는데,
나는 도메인마다 하나의 DTO를 두고,Inner class로 관리한다.

그러면 개요에서 말한 것처럼럼 게시판 목록에 대한 ResponseDto를 함께 만들면 어떻게 되는가..?

class BoardDto {
    public static class OnlyOnethingResponseDto {
        private Long id;
        private String title;
        private String content;
        private LocalDateTime createdAt;
        private LocalDateTime modiedAt;    
    }


    public static class ListResponseDto {
        private String title;
        private LocalDateTime createdAt;
    }
}

요렇게 된다.

개요에서도 말했지만, 나는 지금

"케이스 별로 ResponseDto를 나눠야될까? ,
나누지 않는다고 가정해도, "이 상황에서 굳이 필요가 없는 정보도 줘야할까..?"

라고 고민 중이다..

나는 개인적으로 나누고 싶었다. 구현하는데 쪼금이라도 경험치를 쌓기 위해서..
그리고 그게 좀 더 프론트가 보기엔 좋았을 것이다.(내가 신경쓸 부분은 아니지만 말이다.)
하지만, 실무에서는 어떤 \지 궁금했다. 그래서 한~두가지 찾아보았다.

DTO 관련 글들을 보다 보니 DTO 클래스를 하나로 두고 그 안에 CASE별로 Inner Class로 두는 방식을 많이 사용하는 것 같다. (내가 하는 것처럼)
참고글
위의 글에 링크되어 있는 DTO관련 로그
영한님의 답변이 담긴 글

찾다보니 영한님의 답변도 봤는데,
평소에 강의하실 때에도 명확성을 중요시한다고 했던거로 기억한다.
이 답변에서도 영한님의 평소 가지고 계신 생각으로 답변하고 있는 것 같다.

그리고 중간에 이렇게 말씀하셨는데,
"API를 제공할 때 또 모든 케이스에 대응해서 만들면 API 자체가 너무 많아집니다."
라고 말씀하신다.
명확성도 좋지만, 모든 상황별로 대응한다면 API 자체가 많아진다고,
API가 많아지면 당연히 유지보수 측면에서 어려운 점이 발생할 것이다.

그리고 끝에도 말하시길..
너무 공통화해도 유지보수가 어렵고, 성능 이슈가 있을 수 있고,
너무 대응하도록 만들어도 API 자체가 많아져서 유지보수가 어렵다고 한다..

"딱 봐도 적당한 선을 찾아야 되는구나"라는 생각이 들 것이다.

그리고 GPT한테도 물어봤다.

*나 : *

GPT야 

만약에 

class Board {
private Long id;
private String title;
private String content;
private LocalDateTime createdAt;
private LocalDateTime modifiedAt;
}

이런 게시판 엔티티 클래스가 있다고 가정해보자(애너테이션은 생략한 거 양해 부탁할게).

GetMapping으로 하나의 게시판만 조회할 때는 응답DTO 객체에 지금 선언된 필드들을 다 보여줄 수 있겠지만, 

만약 여러개의 게시판을 보여줘야한다면(예를 들어 전체 게시판 목록같은 것들) 
title 과 createaAt만 보여주면 되잖아??

그럼 백엔드에서 Response용 응답 DTO를 

class BoardDto {


       public static oneThignResponseDto {
                            private Long id;
                            private String title;
                            private String content;
                            private LocalDateTime createdAt;
                            private LocalDateTime modifiedAt;
        }
}


이렇게 하나만 만드는 게 좋을까? 
아니면,

class BoardDto {


       public static class oneThignResponseDto {
                            private Long id;
                            private String title;
                            private String content;
                            private LocalDateTime createdAt;
                            private LocalDateTime modifiedAt;
        }

       public static class ListResponseDto {
                           private String title;
                           private LocalDateTime createdAt;
       }
}


이렇게 목적에 맞게 각각 만들어주는 게 좋을까??

무엇이 더 효율적인지 몰라서 물어봤어.
(오타 혹은 애너테이션 생략은 용서를 구할게)

*GPT : *

두 가지 접근 방식 모두 사용될 수 있지만, 각각의 장단점이 있습니다. 어떤 방식을 선택할지는 상황과 선호도에 따라 다를 수 있습니다.

첫 번째 접근 방식인 단일 응답 DTO 클래스(`BoardDto`)를 사용하는 방식은 코드의 간결성을 유지할 수 있습니다. 모든 필드를 포함한 하나의 응답 DTO 클래스를 만들어서 사용할 수 있으며, 필요한 필드만을 사용하고 나머지는 무시하면 됩니다. 이 방식은 코드의 재사용성을 높일 수 있으며, 필요한 필드가 변경되거나 추가될 경우에도 수정이 쉬워집니다.

두 번째 접근 방식인 여러 응답 DTO 클래스를 사용하는 방식은 목적에 맞는 응답 DTO 클래스를 별도로 정의하여 사용하는 방식입니다. 이 방식은 각각의 응답에 필요한 필드만을 명시적으로 표현할 수 있어 가독성이 높아집니다. 또한, 각각의 DTO 클래스를 사용함으로써 클라이언트에게 반환되는 필드의 목록을 명확하게 제공할 수 있습니다.

효율성 측면에서는 두 가지 방식 모두 큰 차이가 없습니다. 일반적으로 단일 응답 DTO 클래스를 사용하는 방식이 조금 더 간결하고 유지보수가 쉬울 수 있습니다. 그러나 여러 응답 DTO 클래스를 사용하는 방식은 코드의 가독성을 높일 수 있으므로 복잡한 프로젝트에서는 유용할 수 있습니다.

최종 선택은 개발자의 선호도와 프로젝트의 특성에 따라 다를 수 있으며, 어떤 방식을 사용하더라도 명확하고 일관된 코드 스타일을 유지하는 것이 중요합니다.

각각의 장단점을 말해주는데, 요약 해보겠다.

단일 응답DTO 여러 응답 DTO
장점 1. 코드의 간결설
2. 재사용성
3. 필요한 필드만 사용 후 나머지 무시
4. 필드 변경시 수정 용이
1. 필요한 필드만을 명시적으로 표현할 수 있어 가독성이 높아짐.
2. 클라이언트에게 반환되는 필드의 목록을 명확하게 제공할 수 있음.
차이점
1. 효율성 측면에는 없음.
2. 단일 응답 DTO 클래스 사용시 방식이 조금 더 간결하고 유지보수가 쉬움.
3. 여러 응답 DTO 클래스 사용시 코드의 가독성을 높일 수 있으므로 복잡한 프로젝트에서 유용

결론 : 개발자의 선호도

결국 개발자의 성향과 선호도인 거 같다.

나는 왠지 모르게 깔끔하게 정리된 코드가 더 좋다...(나만 그런 건 아닌 거 같다.)
(생활 습관도 그렇긴 함..;; 정신 없는 공간은 보기만 해도 스트레스를 유발한다..)

그리고 하나 더 물어봤다.
Production 코드에서는 어떤 방식을 주로 사용하는지..

Production 코드에서는 여러 응답 DTO 클래스를 사용하는 경우가 많다고 한다.
빨리 실무에 가봐야 될건데.. 조만간이다..!!!

3. 요약 및 결심

DTO를 각각의 케이스마다 만들거나, 단일 응답 객체를 만들거나..
어떤 게 효율적인지 알아보았다.
만, 결론은 개발자의 성향과 프로젝트의 규모와 성격.. 3글자로 요약하면 케바케다..

이번 프로젝트는 규모가 그리 크진 않다.
때문에 나는 응답DTO들을 각각의 케이스 별로 만들어 보겠다.
(사실 도메인마다 그렇게 해봐야 한 두개 추가된다... 이 마저도 mapper가 하기보단 내가 해야겠다.)

끝.

DTO 관련글 (다만 해당 포스팅과는 결은 다른 글..)

728x90
Comments