😀
Hyune's Wiki
  • Welcome
  • Article
    • Link
  • Mentor & Code Reviewer
    • 진행하기에 앞서..
    • Code Review History
      • 한방 쿼리 vs 애플리케이션에서 조립
      • DB에서 TIMESTAMP와 DATETIME 타입의 차이
      • Service는 어떤 dto를 반환해야 할까?
        • 확장 질문
  • Legacy
    • 실무 경험 & 팁
      • Kotlin
        • 파일 조작하기
      • Infra
        • Lightsail
          • 인스턴스 구성 예제
        • 공인 ip 확인하기
      • Database
        • INSERT INTO SELECT SHARED LOCK(row LOCK)
      • API Document
        • OpenAPI (Swagger 3.0)
          • 정적 문서 내보내기
      • Side Project
        • Codesquad
      • ETC
        • HTTP Request 추적하기 with HAR File
    • Study
      • Language
        • Java
          • Copy
          • 메모리 관리
          • Garbage Collection
          • 자료구조
          • Java 17
        • Kotlin
          • Coroutine
      • Framework & Library
        • Spring
          • Spring Security
          • @Component vs @Configuration
        • JPA
          • show-sql 설정의 단점
          • @GeneratedValue strategy
          • Entity의 field type
        • Logback
          • 기본 설정
        • Monitoring
          • VisualVM
            • 설치
            • 문자열 생성으로 테스트
          • nGrinder
      • Database
        • MySQL
          • SQL 문 수행 절차
          • 트랜잭션과 잠금
          • 인덱스
      • Infra
        • AWS
          • S3
            • 용어
            • Amazon SDK 1.x with Spring
          • DynamoDB
            • Get vs Query vs Scan
        • Docker & Kubernetes
      • Computer Science
        • OS
          • Process vs Thread
          • Process
        • Web
          • HTTP
            • HTTP vs HTTPS
            • HTTP 구성
            • HTTP 그외
          • REST API
            • GET 메서드에 payload를 사용해도 되는가?
            • 특정 목적의 API는 어떻게 만들어야 할까?
          • TCP / UDP
          • 인터넷의 작동 원리
          • OAuth 2.0
        • Design Pattern
          • Builder Pattern
        • MSA
        • DDD
      • Test
        • Test Doule
      • Book & Online Class
        • 한 번에 끝내는 Spring 완.전.판 초격차 패키지 Online
          • AOP, Aspect Oriented Programming
          • Data Binding
          • IoC(Inversion of Control), DI(Dependency Injection)
          • Null Safety
          • Spring Resource
          • Spring Boot 버전별 변화
          • SpEL, Spring Expression Language
          • Validation
        • 이펙티브 자바 3판
          • 2장 객체 생성과 파괴
            • 아이템 1. 생성자 대신 정적 팩터리 메서드를 고려하라
            • 아이템 2. 생성자에 매개변수가 많다면 빌더를 고려하라
            • 아이템 3. private 생성자나 열거 타입으로 싱글턴임을 보증하라
            • 아이템 4. 인스턴스화를 막으려거든 private 생성자를 사용하라
            • 아이템 5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라
            • 아이템 7. 다 쓴 객체 참조를 해제하라
          • 3장 모든 객체의 공통 메서드
            • 아이템 11. equals를 재정의하려거든 hashCode도 재정의하라
            • 아이템 12. toString을 항상 재정의하라
            • 아이템 14. Comparable을 구현할지 고려하라
          • 4장 클래스와 인터페이스
      • Webinar
        • 요즘 힙한 스타트업의 DBDB DEEP한 이야기
Powered by GitBook
On this page
  • 이전 리뷰 내용
  • 질문 & 추가 리뷰

Was this helpful?

Edit on GitHub
  1. Mentor & Code Reviewer
  2. Code Review History
  3. Service는 어떤 dto를 반환해야 할까?

확장 질문

PreviousService는 어떤 dto를 반환해야 할까?Next실무 경험 & 팁

Last updated 2 years ago

Was this helpful?

이전 리뷰 내용

service 레이어에서 특정 response(컨트롤러 레이어의 DTO) 를 만들어 반환하지 않고, 범용 DTO를 만들어 반환하게 되면, controller 레이어에서 이 범용DTO 를 가공하여 제공하는 곳에 알맞은 형태의 response 를 가공해서 넘겨줄 수 있다.즉 service 레이어 메서드를 건드릴 일이 없고, 재사용성이 증가한다.

질문 & 추가 리뷰

지난 번 리뷰에서 말씀 해주셨던 내용이 좋다고 생각 했었고, 이번 프로젝트에 적용 해보았는데요. 진행하며 궁금증이 생겨서 dm 드립니다. 범용DTO 라는 특성상 나중에 어떻게 만들어 질지 모르는 response에 대응하기 위해선 범용DTO 안에 로직을 넣어선 안될 것 같았습니다.

  • 네. dto 레이어간의 데이터 이동을 목적으로 하기에 로직이 없는 것이 보통입니다.

The difference between data transfer objects and or is that a DTO does not have any behavior except for storage, retrieval, serialization and deserialization of its own data (, , and ).

이런 생각을 하고 코드를 짜고 보니 결국 범용DTO 는 DB에 쿼리를 날려 얻은 Entity와 완벽히 동일한, 1:1 구조로 나오게 되더라구요.

이것에 대해서는 이야기할 것이 꽤 많습니다. 지금에 맞는 것을 선별적으로 가져가시기를 권장합니다.

  • 필요성을 느끼지 못한다면 dto를 만들지 않는 것도 방법입니다.

    • dto를 만드는 행위 자체도 성능과 유지보수 비용이 발생하기 때문입니다.

  • 지금은 프로젝트 규모가 크지 않기에 범용dto의 의미가 크지 않습니다.

    • 나아가 @Transient를 통해 rich한 entity를 운영할 수도 있습니다.

    • 그렇기에 더더욱 entity가 범용 dto를 대체할 수 있다고 느끼실 수 있습니다.

  • 그렇기에 조금 극단적인 예시를 통해 말하겠습니다.

    • 회사가 매우 커져서 표, 도메인, 영속성 레이어를 각각 모듈화하였다고 가정합니다.

      • 도메인 영역의 반환값을 entity로 할 수 있습니다.

    • 그러던 중 회사의 기술 스택이 바뀌어 JPA를 배제하게 되었습니다.

      • 이 때 entity를 걷어내야되는데, 영속성 레이어의 변화가 표현 레이어까지 영향을 주게 됩니다.

      • 동일한 도메인 로직으로 다른 표현을 했다면 그것에도 영향이 갑니다. (웹 -> 파일)

      • 만약 이것이 같은 회사에서만 쓴 것이 아니라 외부로 공개된 모듈이라면?

        • 우리가 제어할 수 없는 고객사까지 모두 영향을 미치게 됩니다.

    • 현대의 애플리케이션은 매우 복잡하며, 도메인 로직이 풍부하고 중요합니다.

      • 그리고 도메인 로직 외의 기술은 교체 가능 대상입니다.

      • 따라서 도메인 로직은 특정 기술과 무관한 순수 자바로 작성하는 것을 추천합니다.

  • 하지만 이것은 매우 큰 회사에서 다수의 개발자가 동시에 개발하기 위한 방법입니다.

    • 레이어가 엄격히 격리됩니다.

    • 만약 이것을 공부하시려면 육각형 아키텍처까지 보셔야 됩니다.

이러면 service 레이어에서 repository를 호출해 Entity를 얻고, 이 Entity를 그대로 반환하는 것과 어떠한 차이가 있을까? 의문이 들어서 질문 드리고 싶습니다.

  • entity를 service 레이어의 반환형으로 사용하는 것은 기능상 가능합니다. 하지만 레이어를 건너 뛰어버린다는 점에서는 일반적이지 않고 어색합니다.

  • 안티 패턴 중 하나인 osiv 관련 내용을 공부해보시면 좋을 것 같습니다.

business objects
data access objects
mutators
accessors
parsers
serializers
bliki: LocalDTOmartinfowler.com
Logo
Data transfer objectWikipedia
Logo