ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • DTO(Data Transfer Objects)를 왜 쓸까?
    Programming🧑‍💻/Spring 2023. 8. 21. 15:52

    DTO를 사용하는 이유

    DTO(Data Transfer Objects)는 개발할 소프트웨어의 아키텍처가 계층화되어 있어서 각 레이어 간의 데이터의 교환이 필요하거나 외부 시스템과의 상호작용이 있는 경우 데이터를 주고받는 것을 용이하게 만들기 위해 사용하는 데이터 전송용 객체이다. 

    엔티티를 직접 사용하여 정보를 전달할 수 있지만 추후 기술할 이점들 때문에 DTO를 사용한다. 

     

    일단 이해를 위해서 다음과 같은 상황을 가정해 보자.

    당신은 장난감 가게를 운영하고 있으며 다양한 장난감을 보유하고 있으며

    장난감이라는 각 객체는 상품명, 가격, 제조일자, 제조국, 보증기간 등 다양한 정보를 가지고 있다.

    이때 장난감이라는 객체는 변하지 않지만 이 객체를 어디서(계층)에서 다루냐에 따라서 장난감이라는 객체에 대해 필요한 정보가 달라진다. 

    창고

    창고 직원이 관리하는 장난감은 상품명, 가격, 제조국, 제조일자, 제품소재, 입고날짜 등 장난감과 관련된 모든 세부 정보 외에도 재고 관리를 위한 정보같이 장난감의 관리 및 판매에 필요한 모든 세부사항이 라벨에 기재되어 있는 상태로 존재하며 이를 애플리케이션의 엔티티로 볼 수 있다. 

     

    카운터

    손님이 장난감을 주문하면 카운터에서 일하는 계산원은 장난감의 제조국이나 제품소재와 같은 세부정보는 필요가 없다. 단순히 상품명과 가격에 대한 정보만 있으면 계산이라는 업무를 수행할 수 있기 때문이다. 따라서 창고 측에서 카운터로 장난감을 전해줄 때 제품명과 가격만 적혀 있는 상태로 라벨을 변경하여 전해주는데 애플리케이션에서의 DTO로 볼 수 있다. 

     

    웹사이트

    장난감을 판매하기 위해서 웹사이트를 개설하였을 때 웹상에서 창고 내에서 관리 시 필요한 정보인 입고날짜와 같은 정보를 보여줄 필요는 없다. 고객에게 필요한 정보인 상품명, 가격, 제품소재와 같은 정보만 있어도 상품에 대한 설명이라는 목적을 달성할 수 있기 때문이다. 

    따라서 창고 측에서 웹사이트에 필요한 정보를 전해줄 때 필요한 정보만 적혀있는 상태로 라벨을 변경해 전하는데 이 또한 DTO이다. 

     

    즉 DTO란 비즈니스의 각 계층에서 판매, 진열 등 일정한 동작을 수행하기 위해 필수적인 정보를  이해가능하고 가벼운 형태로 전하기 위해서 사용하는 라벨이라고 이해할 수 있다. 

     

     

    DTO의 필요성에 대해서 알았으니 DTO 사용 시 어떠한 장점이 있는지 알아보자. 

     

    비즈니스 로직의 캡슐화

    다음과 같이 `Order`라는 엔티티가 존재하며 해당 클래스 내에는 주문 처리, 할인과 같이 비즈니스 로직과 관련된 메서드들이 객체에 포함되어 있다고 하자. 

    public class Order {
        private List<OrderItem> items;
        private User customer;
        
        // Business logic methods...
        
        public double calculateTotal() {
            // Calculate total with discounts
        }
    }

    고객에게 주문이력에 대한 정보를 제공하고자 할 때 위의 엔티티를 그대로 전달하는 경우, 비즈니스 계층 외의 계층에서 비즈니스 로직에 접근이 가능해지며 엔티티에 대한 잘못된 변경이 일어날 수 있다.  

    public class OrderSummaryDTO {
        private long orderId;
        private double totalAmount;
        
        // Getters and setters...
    }

    대신에 `OrderSummary`라는 DTO를 만들어 정보를 전하게 되면 불필요한 비즈니스 로직에 대한 노출을 막을 수 있다. 

     

     

    효율적인 데이터 전송

    // Directly exposing entity to UI
    List<Product> products = productService.getAllProducts();

    고객을 위한 화면을 그릴 때 엔티티를 직접 가져오게 되면 화면 구성과 관련이 없는 정보들이 너무 많아 클라이언트 단에서 화면을 그릴 때 불필요한 데이터 통신이 많아진다. 

    // Exposing DTOs to UI
    List<ProductDTO> products = productService.getAllProductDTOs();

    따라서 서버 측에서 화면을 구성하는데 꼭 필요한 정보만 추려서 DTO에 담은 뒤 클라이언트 단에 넘기게 되면 전송되는 데이터의 양을 최소화함으로써 효율적인 통신이 가능해진다. 

     

     

    변경에 유연한 설계

    비즈니스를 지속하는 과정에서 새로운 정책이 도입됨에 따라 엔티티에 다음과 같이 새로운 필드가 추가되었다고 가정해 보자. 

    public class Product {
        private String name;
        private double price;
        private double discountPercentage;
        
        // Getters and setters...
    }

    이 때 클라이언트 단에서 보여주는 정보는 그대로인 경우 엔티티를 직접 전송하게 되면 기존의 클라이언트 코드와 충돌을 일으킬 수 있다. 

    public class ProductDTO {
        private String name;
        private double price;
        
        // Getters and setters...
    }

    하지만 만약 DTO를 사용하고 있었다면 엔티티가 DTO로 바뀐 이후 클라이언트에게 전해짐으로 엔티티 변경에 대한 파급효과를 제한할 수 있다. 

     

     

    보안성 향상

    엔티티에 사용자의 개인 정보와 같이 민감한 정보가 포함되어 있는 경우 이를 그대로 외부에 노출하게 되면 보안에 심각한 위기를 초래한다.

    // Directly exposing entity to API
    User getUserInfo(long userId);

    따라서 민감한 정보에 대한 필두는는 API에 노출하기 전에 DTO에서 감춤으로써 사용자 정보 보안성을 향상할 수 있다. 

    // Exposing DTO with restricted fields to API
    UserInfoDTO getUserInfo(long userId);

     

     

     

     

    'Programming🧑‍💻 > Spring' 카테고리의 다른 글

    [Spring] 스프링 필터와 필터 체인  (0) 2023.03.27

    댓글

Designed by Tistory.