정구리의 우주정복

[Spring] 컨트롤러에서 엔티티를 반환해도 될까? 본문

JAVA/STUDY

[Spring] 컨트롤러에서 엔티티를 반환해도 될까?

Jungry_ 2024. 5. 31. 21:42
반응형

공부를 하다가 문득

 

DB 안의 모든 내용을 조회하고 싶으면 컨트롤러에서 엔티티를 직접 리턴해도 되지 않을까 ? 라는 의문이 생겼다

 

나는 습관적으로 DTO 를 만들어서 사용하고 있었기 때문 !

오늘은 이에 대해서 알아보도록 하자

 

결론부터 말하면 안된다 !!!

안되는건 아니고

추천하지 않는다 !!! 하지말라는 말이다 !!!

 

왜일까

가장 쉬운 이유는 

  • 보안성 : 필요한 정보만 선택적으로 노출할 수 있다 + 화면에 필요한 데이터만 선별이 가능하다
  • 유연성 : 요구사항에 맞춰 엔티티와 다른 구조를 가질 수도 있고, DB 의 구조변경이 미치는 영향을 최소화할 수 있다
  • 성능 최적화 : 필요한 데이터만 전송하므로 네트워크 트래픽을 줄일 수 있다

 

몇가지만 더 구체적으로 알아보자면

  • 엔티티는 곧 DB 의 구조이다 !! 그러므로 DB 의 구조를 화면에 그대로 노출하는 것이기 때문에 보안상으로 문제가 될 수 있다
  • API 스펙과 엔티티 사이에 의존성이 생기게 될 수 있다
  • JPA 를 사용하면 양방향 매핑을 하는 경우가 생기는데 이때 순환참조가 발생할 수 있따

화면에 필요한 데이터를 전송하는 역할은 DTO 에게 위임해주면 좋을듯 하다

 

 

그렇다면 만약 

엔티티 -> DTO

DTO -> 엔티티 

로 변환하고 싶은 경우에는 어떻게 해야할까 ?

 

보통은 Mapper 클래스를 두고 변환을 한다고 한다 !! 

 

그래서 한번 만들어본 Mapper

RecommendMapper.java

import com.example.toygry.dto.RecommendResponse;
import com.example.toygry.entity.Recommend;

public class RecommendMapper {
    // entity -> dto
    public static RecommendResponse toDto(Recommend recommend) {
        if (recommend == null) {
            return null;
        }

        return RecommendResponse.builder()
                .id(recommend.getId())
                .userId(recommend.getUserId())
                .password(recommend.getPassword())
                .recommendType(recommend.getRecommendType())
                .title(recommend.getTitle())
                .contents(recommend.getContents())
                .image(recommend.getImage())
                .createdDate(recommend.getCreatedDate())
                .modifiedDate(recommend.getModifiedDate())
                .build();
    }

    // dto -> entity
    public static Recommend toEntity(RecommendResponse recommendResponse) {
        if (recommendResponse == null) {
            return null;
        }

        return Recommend.builder()
                .id(recommendResponse.getId())
                .userId(recommendResponse.getUserId())
                .password(recommendResponse.getPassword())
                .recommendType(recommendResponse.getRecommendType())
                .title(recommendResponse.getTitle())
                .contents(recommendResponse.getContents())
                .image(recommendResponse.getImage())
                .createdDate(recommendResponse.getCreatedDate())
                .modifiedDate(recommendResponse.getModifiedDate())
                .build();
    }
}

 

    /**
     * id 에 해당하는 게시글 조회
     *
     * @param id 게시글의 id
     * @return id 에 해당하는 게시글
     */
    public RecommendResponse getRecommend(String id) {
        Recommend recommend = recommendRepository.findById(id);
        return RecommendMapper.toDto(recommend);
    }

 

실제 사용은 이런식으로 하게 된다

 

 

참고 링크

https://tecoble.techcourse.co.kr/post/2020-08-31-dto-vs-entity/

반응형
Comments