Entity를 감추기
Entity가 뷰, API 응답에 바로 노출될 때의 비용
- 캡슐화를 지키기 어려워짐
- 꼭 필요하지 않은 속성도 외부로 노출되어 향후 수정하기 어려워짐
- JSP, Freemarker에서의 객체 참조
- 컴파일 시점의 검사 범위가 좁다 → entity클래스를 수정했을 때 뷰에서 에러가 나는 경우가 뒤늦게 발견됨
- JPA를 쓴다면 OpenEntityManagerInViewFilter 를 고려해야 함
- 초보 개발자는 쿼리가 실행되는 시점 예상못함
- JSON 응답
- @JsonIgnore, @JsonView 같은 선언이 많아지면 Json의 형태를 클래스만 보고 예측하는 난이도가 올라감
외부 노출용 DTO를 따로 만들기
- ENTITY → DTO 변환 로직은 컴파일 타임에 체크된다
- DTO는 비교적 구조를 단순하게 가져갈 수 있다
- 더 단순한 JSON 응답, JSP에서 쓰기 좋은 구조를 만들기에 유리하다.
- DTO의 변화는 외부 인터페이스로 의식해서 관리하는 범위가 된다.
- 예: Swagger 스펙 활용
- 여러 ENTITY를 조합할수 있는 여지가 생긴다.
- 서비스에서 컨트롤러에 응답값으로 dto로 변환해서 반환할거냐 혹은 entity반환하고 컨트롤러에서 dto로 변환해서 반환할것이냐
- 서비스에서 dto로 변환하는건 김영한님 스타일
- 컨트롤러에서 dto로 반환하더라도 서비스에서 나온 도메인 모델을 컨트롤러에서 바꾸는 이상한 행동만 하지 않는다면 상관 없다!(우기 멘토님)
- 서비스에서 웹의 모델을 알 고 있는건 이상하다 → 이럴 경우, 웹 모델 변경할 때 서비스까지 들어가서 바꿔주고 들여 봐야함
DTO의 이름 고민
- 역할별로 구분된 DTO 정의 예
- 이슈 조회 JSON 응답 : IssueResponse, IssueDto, IssueDetailDto
- 이슈 생성 JSON 요청 : IssueCreationRequest, IssueCreationCommand
- 이슈 조회 조건 : IssueQuery, IssueCriteria
- 이슈 DB 통계 조회 결과 : IssueStatRow
- 이슈 + 코멘트 복합 조회 결과 : IssueCommentRow
Exception
- 레이어 별로 Exception을 따로 정의해서 해야 함
- 서비스 레이어에서 사용하는 Exception, 리포지토리 레이어에서 사용하는 Exception 들이 따로 존재함
- 리포지토리에서 발생하는 exception이 서비스 레이어에서 throw하도록 하는 것 좋지않음