본문 바로가기
Refactoring/ReviewRanger

[리뷰레인저] 페이징에 사용되는 Slice 도메인 객체의 노출 범위를 조정하자 - 3

by 수짱수짱 2024. 4. 12.

해당 게시글은 프로젝트 '리뷰레인저'에 대해 개인 리팩토링 과정을 정리한 시리즈 글입니다.

이번 게시글의 주제는 '페이징에 사용되는 Slice 객체가 외부에 노출되는 현상에 대한 개선안'입니다.


개요

Slice 객체는 spring.data 패키지에 존재하는 것을 바탕으로 리팩토링을 진행하자! (패키지 범주를 잘 생각해보자)

 

우리가 왜 controller에서 entity를 노출하지 않는가? 외부에 의해 수정될 위험이 있기때문이다

entity는 domain영역이다. 마찬가지로 slice 객체도 domain영역에 존재한다.

그래서 entity 대신에 우리는 Response라는 객체를 만들어 사용한다

이와 똑같은 맥락으로 생각해보면 된다

 

Slice 객체의 범주

Controller → Service → Repository(DAO)

domain은 이 중 어디에 있을까? Service와 Repository 사이에 존재하는 것이 domain이다

 

Controller → Service → (domain) → Repository(DAO)

Entity도 domain 영역이기 때문에  위의 사진 처럼 우리가 `Repository`에서 Entity 그대로 받아오는 것을 생각하면 문제가 없다

 

마찬가지로 위 사진처럼 `Slice`도 `Repository에 있어도 같은 레벨(domain)이기 때문에 문제가 없다

 

하지만 Controller로 내려줄 때 Entity를 그대로 노출시키진 않는다

위 사진처럼 Response로 한 번 감싸서 노출시킨다

 

그렇다면? 마찬가지이다. 레벨이 다른 Slice도 Controller에 노출이 되면 안되는 것이다

하지만 기존의 코드는 Controller에 Slice가 그대로 노출되어 있다.

우리가 Response 객체를 만들어 노출시키는 것 처럼 Slice도 SliceResponse를 만들어 노출시켜야 하는 것이다

 

 

수정 후 코드

SliceResponse DTO

먼저 Controller에 노출시킨 Slice 객체를 대신 할 `SliceResponse DTO`를 생성해 준다.

제네릭 타입 T로 받아 다양한 데이터가 올 수 있도록 한다. `SliceResponse<T>, List<T> data`

 

Slice data - Content Type Dto

 

해당 DTO는 기존 Slice에서 사용하던 DTO이다 (=아래 JSON 사진의 data 빨간 블럭의 데이터)

 

`FinalReviewResultService` Return타입을 기존의 Slice에서 `SliceResponse`로 변경시켜준다

controller에서 service 로직을 호출했을 때 반환값으로 `SliceResponse`가 오게되어 Controller에서 `Slice`에 대한 의존성이 없어진다

 

`FinalReviewResultController`에서도 Response의 데이터 타입을 `Slice`에서 `SliceResponse`로 변경해준다.

따라서 외부에 노출되는 데이터는 `Slice`가 아닌 `SliceResponse`가 노출된다!

 

똑같이 spring의 data.domain에 존재하는 `PageRequest`과 `Pageable`도 Service로 넘겨주었다

인자로 주던 `Pageable`을 없애고 요청으로 들어온 size를 인자로 넘겨준다.

이후에 service에서 해당 size값으로 `Pageable` 객체를 생성하도록 했다

 

controller에서 data.domain의 의존성이 활성화되지 않는 모습을 확인할 수 있다

이렇게 최종적으로 Controller의  data.domain에 대한 의존성이 제거된 모습을 확인 할 수 있다!

 

리팩토링 후기

공부했던 내용을 다시 돌아보면 단순히 `Slice` 객체를 커서 페이징에 사용하지 않으니 리팩토링이 필요하다 라고 작성 해놨다

저렇게 적었던 이유는 분명히 `Slice` 객체가 domain에 해당하는지도 모르고 `controller`에서 domain을 노출하지 않는다는 점도 놓쳤기 때문에 적었을 것이다..

우리가 mvc 구조를 사용하는 이유를 다시 생각해보고 각 범위에 맞는 객체 노출 범위를 적정하게 설정할 수 있는 것도 개발자의 역량임을 깨닫게 된 계기가 되었다.