[아키텍처] 데이터 맵핑

데이터 관련 객체

애플리케이션 및 시스템의 동작을 위해서는 시스템(계층) 간, 애플리케이션 내 레이어 간 데이터 이동이 필요하다. 하나의 애플리케이션이 내외부적으로 데이터를 처리하기 위해 사용하는 객체의 종류는 다음과 같다.

요청/응답 객체

클라이언트가 서버 애플리케이션에게 필요한 데이터를 요청하고 서버는 응답으로 클라이언트에게 데이터를 응답으로 준다. 이 경우 요청 데이터와 응답 데이터를 담을 객체가 필요하다.


데이터 전송 객체

데이터 전송 객체(DTO, Data Transfer Object)는 레이어 간 데이터를 전달하기 위해 데이터를 담는 컨테이너 역할만 수행하는 객체이다.

애플리케이션의 레이어드(layered) 아키텍처 구조에서는 역할이 논리적으로 서로 분리된 레이어 간 데이터가 이동한다. 각 레이어마다 데이터를 담고 있는 객체를 정의하는 경우 레이어 간 데이터 전달 시 객체를 서로 매핑(또는 변환)하는 과정이 필요하다. 도메인 모델 객체를 중심으로 데이터를 주고 받는 아키텍처 구조(예: 헥사고날(hexagonal) 아키텍처)에서도 마찬가지로 레이어(또는 영역) 간 데이터 전달 및 매핑 과정이 수반된다. 이때 레이어 간 데이터 매핑을 수행하는 객체를 데이터 매퍼(mapper) 객체라고 한다. 각 레이어 및 영역에 전용 데이터 객체를 정의하지 않는 경우 매핑 처리된 DTO를 사용하게 된다.

DTO 객체는 비즈니스 로직과 관련된 데이터를 외부로부터 숨기는 데이터 캡슐화를 위해서도 사용된다. 클라이언트가 서버에게 데이터를 요청하는 경우 정의된 도메인 모델 객체의 모든 속성을 그대로 전달하지 않고 클라이언트가 필요한 데이터만을 선별하여 응답 데이터를 DTO 객체로 구성함으로써 서로 다른 클라이언트 별로 서로 다른 응답 데이터를 구성할 수 있다. 내부 도메인 모델 객체의 속성명을 변경하거나 필요한 데이터만을 응답하는 언더페칭(underfetching)을 수행하기 위해 데이터 매핑 및 DTO 객체 생성 후 클라이언트에게 전달하는 과정이 필요할 수 있다. DTO 객체에는 비즈니스 로직이 담기지 않는다.

DTO를 사용하면 레이어 간 데이터 전달 시 레이어 간 메서드 호출을 최소화할 수 있다. 데이터를 전달하는 레이어는 데이터 매퍼 객체를 통해 DTO 객체를 만들고 데이터를 전달받는 레이어는 완성된 DTO 객체를 전달받으면 된다. 애플리케이션 내 논리적 구분인 레이어 간 데이터 전달 뿐만 아니라 물리적으로 구분된 시스템(계층) 간 데이터 전달 시에도 DTO가 사용된다.

헥사고날 아키텍처를 사용하여 애플리케이션을 구성할 경우 외부 영역과 내부 영역 간 데이터 전달이 필요하다. 이때 내부 영역의 도메인 모델 객체를 외부 영역의 DTO로 매핑하는 과정이 필요하게 된다. 이때 내부 영역에서 도메인 모델 객체를 DTO로 변환한 후 외부 영역으로 반환할 것인지, 아니면 내부 영역은 매핑에 대한 관여 없이 도메인 모델 객체를 반환하기만 하고 외부 영역에서 도메인 모델 객체를 DTO로 매핑할 것인지에 대한 고민이 생기게 된다.

내부 영역이 외부 영역의 DTO 객체를 가지고 있는 것을 지양한다면 내부 영역의 서비스 구현체가 도메인 모델 객체를 반환하게 하고, 외부 영역의 컨트롤러에서는 내부 영역에서 받아온 도메인 객체를 DTO로 매핑하면 된다. 반면 데이터 변환에 비즈니스 로직이 포함된다면 데이터 매핑을 내부 영역에서 하는 것이 좋을 수도 있다. 이 경우 비즈니스 로직이 담긴 매핑 역할을 하는 클래스를 내부 영역에 위치시키고 매핑 메서드는 도메인 모델 객체를 인자로 받고 객체 프로퍼티를 적절히 매핑한 후 새로운 DTO 객체를 생성하여 반환하도록 한다. 그리고 서비스 구현체에서 해당 매핑 메서드를 호출한다.


엔티티 객체

비즈니스 및 도메인 개념을 표현하기 위한 객체를 엔티티(entity) 객체라고 한다. 비즈니스 규칙과 비즈니스 데이터를 결합하고 이를 객체로 표현하기 위한 것이 엔티티이다. 엔티티 객체는 식별 가능한 속성(식별자)을 가지고 있으므로 고유하다. 따라서 식별자의 비교를 통해 엔티티 객체를 구분할 수 있다. 엔티티 객체는 생성 후 변경이 가능한 가변(mutable) 객체이다. 엔티티 객체에는 비즈니스 로직이 담길 수 있다.

관계형 데이터베이스를 사용하여 데이터를 영속화하는 애플리케이션의 경우 개체-관계 모델에 따라 구조화된 테이블에 데이터를 저장한다. 객체 모델과 관계형 모델을 서로 매핑하는 ORM 기술을 사용하는 경우 테이블 구조와 1:1로 매칭하기 위한 객체가 필요하며 이를 엔티티 객체라고 한다. 테이블의 스키마 구조가 엔티티 객체에 반영되며, 데이터베이스로부터 데이터 조회 시 엔티티 객체에 데이터가 포함된다. 애플리케이션은 데이터베이스의 테이블로부터 데이터를 조회하고 이를 객체로 매핑하기 위해 개념적으로 테이블에 매핑되는 엔티티 객체를 가지고 있어야 한다.


값 객체

속성이 한 번 정해지면 변하지 않는, 개념적으로 완성된 객체를 값 객체(VO, Value Object)라고 한다. 값 객체는 일단 생성되면 변경할 수 없는 불변(immutable) 객체이다. 엔티티와 달리 식별자에 따라 구별되지 않으며 속성값의 비교를 통해 값 객체를 구분하고 동등성(equality) 비교를 수행한다.


엔티티와 DTO


자바의 롬복과 Record


참고

Comments