프로그래밍 언어/java

[Java ] 3-Tier 아키텍처와 DTO:

하루이2222 2024. 8. 24. 20:41

웹 애플리케이션을 개발할 때 "사용자가 입력한 데이터는 어디로 가서 어떻게 처리될까?"라는 질문은 아키텍처 설계의 가장 기본이 되는 질문입니다. 이 데이터의 여정을 체계적으로 안내하는 지도가 바로 3-Tier 아키텍처이며, 이 여정에서 데이터를 안전하게 실어 나르는 전용 차량이 DTO(Data Transfer Object)입니다.

오늘은 웹 애플리케이션의 뼈대를 이루는 3가지 계층과, 각 계층 사이에서 데이터가 어떻게 DTO를 통해 안전하게 이동하는지 알아보겠습니다.

1. 애플리케이션의 3가지 핵심 계층

견고한 웹 애플리케이션은 보통 세 가지 주요 계층으로 역할을 나눕니다. 각 계층은 자신만의 명확한 책임이 있습니다.

① 프레젠테이션 계층 (Presentation Layer) - 고객을 맞이하는 창구

  • 역할: 사용자와 직접 상호작용하는 UI 화면이나 API 엔드포인트를 제공합니다. 사용자의 요청을 가장 먼저 받고, 처리된 결과를 사용자에게 보여주는 역할을 합니다.
  • 대표 컴포넌트: Spring의 Controller

② 서비스 계층 (Service Layer) - 실질적인 업무를 처리하는 사무실

  • 역할: 애플리케이션의 핵심 비즈니스 로직을 처리합니다. 프레젠테이션 계층에서 받은 요청을 해석하고, 비즈니스 규칙에 따라 데이터를 가공하거나 계산을 수행합니다. 필요하다면 데이터 접근 계층에 데이터 처리를 요청합니다.
  • 대표 컴포넌트: Service

③ 데이터 접근 계층 (Data Access Layer) - 데이터를 보관하는 창고

  • 역할: 데이터베이스와 직접 상호작용하며 데이터의 영속성(Persistence)을 관리합니다. 데이터를 생성(Create), 조회(Read), 수정(Update), 삭제(Delete)하는 CRUD 작업을 전담합니다.
  • 대표 컴포넌트: Repository

2. 데이터의 여정: 요청부터 응답까지

사용자가 '회원가입' 버튼을 눌렀을 때, 데이터는 다음과 같은 여정을 떠납니다.

  1. 요청 접수 (📥 프레젠테이션 계층)
    사용자가 입력한 ID, 비밀번호 등의 데이터가 HTTP 요청을 통해 컨트롤러에 도착합니다. 이때 컨트롤러는 데이터를 DTO에 담아 받습니다.

  2. 업무 지시 (⚙️ 프레젠테이션 계층 → 서비스 계층)
    컨트롤러는 받은 DTO를 서비스 계층에 전달하며 "이 정보로 회원가입 비즈니스 로직을 처리해달라"고 요청합니다.

  3. 데이터 처리 요청 (💾 서비스 계층 → 데이터 접근 계층)
    서비스는 비즈니스 로직(예: 비밀번호 암호화)을 수행한 후, 가공된 데이터를 Entity 객체로 만들어 데이터 접근 계층(리포지토리)에 전달하며 "데이터베이스에 저장해달라"고 요청합니다.

  4. 데이터 처리 결과 반환 (📤 데이터 접근 계층 → 서비스 계층)
    리포지토리는 데이터베이스 작업을 마친 후, 저장된 Entity를 서비스 계층으로 반환합니다.

  5. 결과 보고 (✅ 서비스 계층 → 프레젠테이션 계층)
    서비스는 모든 비즈니스 로직을 완료한 후, 사용자에게 보여줄 결과(예: "회원가입 성공")를 다시 DTO로 변환하여 컨트롤러에 반환합니다.

  6. 최종 응답 (✨ 프레젠테이션 계층 → 사용자)
    컨트롤러는 서비스로부터 받은 DTO를 바탕으로 사용자에게 보여줄 최종 응답(JSON, HTML 등)을 생성하여 반환합니다.


3. DTO는 왜, 그리고 어디에 사용하는가?

DTO(Data Transfer Object)는 이름 그대로 계층 간 데이터 전송을 위한 전용 객체입니다. 그렇다면 데이터베이스와 직접 매핑되는 Entity를 그대로 사용하면 안 될까요? 정답은 "아니오" 입니다. DTO를 사용하는 이유는 다음과 같습니다.

Entity를 직접 노출하는 것은 우리 집의 모든 방 열쇠를 외부인에게 주는 것과 같습니다.

  1. 프레젠테이션 계층의 입력 데이터 처리

    • 사용자 입력은 항상 유효하지 않을 수 있습니다. DTO를 사용하면 @Valid 어노테이션 등으로 유효성 검증을 DTO에서 처리할 수 있습니다.
    • Entity의 모든 필드가 아닌, 화면에 필요한 데이터만을 DTO로 정의하여 받을 수 있습니다.
  2. 서비스와 프레젠테이션 계층 간의 데이터 전달

    • Entity는 데이터베이스와 관련된 민감한 정보(예: 비밀번호)나, 화면에는 불필요한 정보(예: 내부 식별자)를 포함할 수 있습니다. DTO를 사용하면 화면에 필요한 데이터만 선택적으로 가공하여 전달함으로써 보안을 강화하고 API 스펙을 명확하게 할 수 있습니다.
  3. 외부 API와의 통신

    • 외부 시스템과 데이터를 주고받을 때, 상대방의 API 명세에 맞는 DTO를 사용함으로써 우리 시스템의 내부 데이터 구조(Entity)와 외부를 완벽하게 분리할 수 있습니다.

요약: Entity와 DTO의 명확한 경계

구분 Entity DTO (Data Transfer Object)
역할 데이터베이스와 매핑되는 핵심 도메인 객체 계층 간 데이터 전송을 위한 래퍼(Wrapper) 객체
핵심 로직 비즈니스 로직을 포함할 수 있음 (Domain-Driven) 순수 데이터 컨테이너 (Getter/Setter만 존재)
주요 사용 계층 서비스 계층, 데이터 접근 계층 프레젠테이션 계층과 서비스 계층 경계
생명주기 데이터베이스와 함께하는 영속적인 상태 요청과 응답 사이에서 생성되고 소멸됨

마치며

3-Tier 아키텍처와 DTO는 단순히 코드를 나누는 규칙이 아니라, 각자의 역할과 책임을 명확히 하여 유지보수하기 쉽고, 확장 가능하며, 안전한 애플리케이션을 만들기 위한 설계 철학입니다.