[뉴스 APP] 데이터를 DTO로 반환하기

김성수·2023년 5월 3일
1

뉴스어플리케이션

목록 보기
1/5

데이터를 프론트엔드(클라이언트)로 보낼 때 엔티티 타입으로 보내는건 바람직하지 않다.
이유는 여러가지가 있다.
API 스펙, 데이터 유실, 원치 않는 데이터 전송, 엔티티 수정 불가 문제... etc
따라서, 엔티티 대신 DTO 객체를 만들고 API 스펙에 맞게 보내주는게 더 좋은 방안이다.



컨트롤러에서 엔티티 -> DTO로 변환하기

엔티티 값을 DTO로 변환해서 반환하는 방법은 여러가지겠지만,

얼마전에 배운 stream(), map() 메서드가 떠올라서 바로 적용해봤다.

JPA는 엔티티로 소통하기 때문에 값을 저장하거나, 값을 가져올 때 반드시 엔티티로 접근해야 한다.

그래서, 따로 DTO로 변환을 하는 작업이 필요하다.



컨트롤러에서 DTO로 변환해준 이유

비즈니스 로직에서 DTO로 값을 반환해주게 되면 반환 스펙이 정해져버려서 나중에 API 스펙이 변경되었을 때 확장하는데 어려움이 있다고 판단했다.

예를 들어, DB에서 모든 데이터를 가져오고 거기서 제목, 컨텐츠, 작성자 정보, 작성 날짜 데이터를 반환받고 싶은데

비즈니스 로직에서 제목과 컨텐츠만 반환해주도록 로직이 구현되어 있으면

새로운 비즈니스 로직을 만들어야 한다.


하지만, 컨트롤러에서는 DTO로 변경해줄 때

내가 원하는 데이터만 골라서 담아줄 수 있다.

바로 stream() 메서드를 사용해서 말이다!


만약 DTO로 값을 반환하지 않는다면 아래와 같은 코드로 작성될 것이다.
    @GetMapping("/")
    public String home(Model model) {

        List<News> results = newsService.findNewsAll();

        model.addAttribute("results", results);

        return "/home";
    }

이렇게 되면 엔티티를 바로 전달하게 되므로,

여러 문제가 발생할 수 있다!


아래 코드는 stream()을 사용하여 데이터를 반환해주는 코드이다

    @GetMapping("/")
    public String home(Model model) {

        List<News> news = newsService.findNewsAll();

        List<NewsListDto> results = news.stream()
                .map(m -> new NewsListDto(m.getTitle(), m.getContent()))
                .collect(Collectors.toList());

        model.addAttribute("results", results);

        return "/home";
    }

stream 객체로 내가 원하는 title 값과 content 값만 가져와서

collectors.toList() 메서드를 이용해 List 타입이면서 NewsListDto로 반환하는 results 객체에 값을 담아줄 수 있게 되었다.



의심이 들다

그런데,

정말 타이틀 값과 컨텐츠 값만 담아서 results 객체에 담게될까?

내부 작동 과정이 궁금하다.

조금 생각해보니

new NewsListDto(m.getTitle(), m.getContent())

코드는 내가 NewsListDto에 오버로딩한 생성자이다.

이 생성자가 요구하는 데이터만 담겨서 객체에 저장될 수 밖에 없다.

따라서 내가 원하는 title값과 contents 값만 results에 담기게될 것이다.



느낀점

어제 배운 따끈따끈한 지식을 어플리케이션을 만들면서 적용해봤다는 사실이 너무 뿌듯하고 기분이 좋다.

앞으로 내가 알지 못하는 새로운 기술들을 배우고 적용해나갈텐데

설레는 마음이 든다..

찐개발자가 되어가는걸까..?

profile
깊이 있는 소프트웨어 개발자가 되고 싶습니다.

0개의 댓글