😀
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
  • 리뷰 대상 코드
  • 장점
  • 단점
  • 예시
  • 어떻게 해야되냐?
  • CQRS 모델을 고려하신 것이라면 지금도 나쁘지는 않습니다.
  • 재사용을 고려한다면
  • 하지만
  • 기타 참고 사항

Was this helpful?

Edit on GitHub
  1. Mentor & Code Reviewer
  2. Code Review History

Service는 어떤 dto를 반환해야 할까?

리뷰 대상 코드

public Slice<DishListResponse> findDishesByCategory(String categoryName, Criteria criteria) {
        List<Dish> dishes = dishRepository.findByCategoryName(
            categoryName, criteria.getLimit(), criteria.getOffset());

        List<DishListResponse> responses = dishes.stream()
            .map(DishListResponse::from)
            .collect(Collectors.toList());
        return new Slice<>(responses, criteria);
    }
  • 33조의 코드를 보면 service에서 조회 메서드를 통해 dto를 반환합니다.

  • 그런데 response라는 네이밍에서 유추할 수 있듯이 외부로 바로 반환되는 dto입니다.

장점

  • 해당 화면/기능만을 로직이 완전히 분할되어 개발이 편하고 변경에 강합니다.

  • 개발이 편하다는 것이 별 것 아니라고 생각할 수 있습니다.

    • 하지만 간결성이나 익숙한 패턴의 사용, 일관성 있는 코딩은 생산성에 지대한 영향을 줍니다.

단점

  • 기능이 특화되는 만큼 재사용성이 떨어집니다.

예시

  • 33팀은 공통 플랫폼/OpenApi을 만드는 팀입니다.

  • DishListResponse는 아래와 같은 필드를 가지고 있습니다.

    private final String title;
    private final String description;
    private final Integer fixedPrice;
    private final Integer discountPrice;
  • AAA 사이트에서는 해당 API로 잘 쓰고 있었습니다.

  • 그런데 어느날 신설된 BBB 사이트에서는 영문 title 반환이 필요해졌습니다.

    • response이 형태가 달라진 것입니다.

    • 단순히 engTitle만 추가하면 된다고 생각할 수 있지만, BBB 사이트를 위해 수정한 response는 AAA 사이트에도 노출된다는 것이 문제입니다.

    • 즉 의도하지 않은 사이드 이펙트가 생김으로 인해 재사용성이 떨어집니다.

  • 만약 지금의 구조에서 AAA 사이트에 영향을 주지 않으면서 BBB 사이트의 니즈를 만족하려면, BBB 사이트를 위한 response를 반환하는 메서드를 새로 만들어야 합니다.

    • 이미 만들어진 response를 transform하는 것은 추천하지 않습니다.

어떻게 해야되냐?

CQRS 모델을 고려하신 것이라면 지금도 나쁘지는 않습니다.

  • 실제로 해당 기능이 특화된 경우 지금의 구조도 좋습니다.

    • 리소스 기반이 아닌 니즈 기반의 API 설계가 필요한 경우가 있습니다.

      • 대표적으로는 사내 어드민에 그리드 형태의 화면을 만들 때 입니다.

      • 이 경우 다수의 테이블을 조인하고 response를 projection하는 형태로 설계하여 repository 레벨에서부터 response를 반환할 수도 있습니다.

    • 하지만 이것이 의도한 것이라면 좀 더 특화된 네이밍과 클래스 분리를 하는 것이 좋습니다.

재사용을 고려한다면

  • 좀 더 리소스를 기반으로 사용하기 위한 고민이 필요합니다.

  • 한가지 예로는 service에서는 범용 dto를 반환하고 controller에서 api에 맞는 특화 response를 만들 수 있습니다.

  • 즉 레이어별로 input, output dto를 만들면 결합도가 낮아져 재사용성은 높아집니다.

하지만

  • 사이드 프로젝트와 같이 기간이 한정되고 큰 요구사항의 변화가 없는 경우 재사용만을 고려하는 것은 과할 수 있습니다.

    • 네이밍의 고민과 페어에게 로직을 설명해야되는 수고가 생깁니다.

  • 실무에서도 마찬가지이기에 생산성과 재사용/변경의 사이에서 트레이드 오프 하셔야됩니다.

    • 저도 실무에서는 확장성이 거의 예상되지 않는 업무는 의도적으로 구조화하지 않기도 합니다.

기타 참고 사항

  • CQRS 패턴

  • BFF (백엔드 포 프론트)

  • 언제 올지 모르는 너무 먼 미래보다는 지금의 요건에 충실하게 만들자.

PreviousDB에서 TIMESTAMP와 DATETIME 타입의 차이Next확장 질문

Last updated 2 years ago

Was this helpful?