Entity와 Dto

2024. 1. 9. 10:08
728x90

엔티티를 직접 반환하고 사용하고 있는데, 뭔가 말이 안된다는 느낌이 든다... 

데이터베이스에 직접 왔다갔다 하는게... 괜히 엄청나게 위험한 행동인듯한 느낌..

그리고 DTO를 만들어두고서는 사용을 한번도 안한것도 이상하다. 

 

 

DTO는 Data Transfer Object로 클라이언트와 서버 간 데이터 전송을 위해 설계된 객체.

Entity는 데이터베이스에 저장되는 데이터 객체. >> 이것만이 데이터베이스와 직접적으로 연결되게 된다.

 

 

Entity를 직접 반환할 경우 여러가지 문제가 생긴다.

1) 필요한 데이터만 전송하기 어렵다. : 엔티티 반환시 엔티티에 존재하는 모든 데이터가 반환된다. 불필요한 데이터를 사용자에게 전달하게 될 수 있다.

2) 순환 참조 문제 : 엔티티 간에 양방향 관계가 존재할 경우, 엔티티 반환하는 순간 순환 참조로 무한 JSON 직렬화 이슈가 발생할 수 있다.

3) 보안 문제 : Entity를 반환하면 테이블 자체를 공개하는 것이므로 민감한 정보가 노출될 가능성이 있다. 

4) 엔티티 구조 변경시 발생하는 문제 : 요구사항이 변경되어 엔티티의 구조가 변경될 경우 추가 작업이 요구된다. 효과적인 유지 보수가 어렵고 시간과 비용이 증가한다.

 

그렇다면 Entity와 DTO를 분리하면 어떻게 될까?

1) 필요한 데이터만 선별하여 서버 사용량 최소화 : DTO는 서버에서 클라이언트에 데이터를 전송하는데 사용된다. 필요한 필드를 재정의하여 필요한 데이터만 전송할 수 있어서 전송 데이터양과 네트워크 대역폭 사용량이 최적화되어 더 빠른 응답시간과 전송시간을 얻을 수 있다.

2) 순환 참조 예방 : DTO는 엔티티 간의 양방향 참조가 포함되지 않은 간단한 구조를 가진다. 

3) 보안 강화 : 테이블 구조는 서버측에만 알 수 있으므로 API 보안성을 강화시킬 수 있다. 

4) 엔티티 구조가 변경되어도 안전 : 엔티티 구조가 변경되더라도 이 변경사항이 클라이언트에 직접적으로 영향을 미치지 않는다. 서버 간의 결합도를 낮추고 유지보수가 용이해진다.

5) Validation 코드와 모델링 코드 분리

 - validation 코드 : @NotNull, @NotEmpty, @NotBlank

 - 모델링 코드 : @Column, @JoinColumn, @ManyToOne, @OneToOne 등

: Entity에는 모델링을 위한 코드가 추가되는데 여기에 validation 코드가 들어가게 된다면 더 복잡해지고 가독성이 떨어진다. 각각의 요청마다 다른 Dto를 만들어 상황에 따라 필요한 validation을 추가한다면 Entity클래스의 모델링에 집중할 수 있다. 

 

 

1) Controller : 클라이언트의 요청을 받고 응답을 반환. DTO의 형태로 데이터를 받아 서비스에 전달.

2) Service : 비즈니스 로직을 수행하며 데이터 처리를 담당. 컨트롤러에서 받은 DTO를 Entity로 변환하고, 필요한 작업을 수행한 뒤에 Repository에 Entity를 전달

3) Repository : 데이터베이스와의 인터페이스 역할. 서비스에서 Entity를 전달 받아 영속화를 처리.

 

 

** Entity <-> DTO 변환 메서드 구현

@Getter
@NoArgsConstructor
public class PostsSaveRequestDto {
 
    @NotEmpty
    private String title;
 
    private String content;
 
    private String author;
 
 // 생성자에서 변환하는 방법
    public PostsSaveRequestDto(Posts posts) {
    	this.title = posts.getTitle();
        this.content = posts.getContent();
        this.author = posts.getAuthor();
    }
 
 // -----------------------------------------------------------
 
 // Builder 패턴 활용하는 방법
 	@Builder
	public PostsSaveRequestDto(String title, String content, String author) {
    	this.title = title;
        this.content = content;
        this.author = author;
    } 
    
    // 엔티티로 변경
    public Posts toEntity() {
        return Posts.builder()
                .title(title)
                .content(content)
                .author(author)
                .build();
    }
    
    // DTO로 변경
    public PostsSaveRequestDto toDto(Posts posts) {
        return PostsSaveRequestDto.builder()
                .title(posts.getTitle())
                .content(posts.getContent)
                .author(posts.getAuthor)
                .build();
    }
}

 

 

일단 이렇게 적용하여 프로젝트를 진행해보아야겠다.

728x90

BELATED ARTICLES

more