이 포스팅은 신선영 저, 『스프링 부트 3 백엔드 개발자 되기』(골든래빗, 2023)를 공부하면서 핵심 개념들을 정리하기 위해 작성하였습니다.
백엔드의 계층은 프레젠테이션 계층(컨트롤러), 비즈니스 계층(서비스), 퍼시스턴스 계층(리포지토리)로 나뉘어서 볼 수 있다. 하지만 이러한 3계층 구조는 서버 내부 로직에 한정된 설계 원칙이다. 이번 장에서는 타임리프를 이용하여 사용자가 실제로 이용하는 화면인 UI까지 구현하려고 한다. 프론트엔드를 포함한 프로그램 전체적인 관점에서 봤을 때에는 MVC 모델로 계층을 나누는 것이 더 적절하다.
□ MVC 모델
MVC 모델은 한 프로그램의 전체 구조를 Model, View, Controller라는 세가지 계층으로 나누어서 설명하는 모델이다. 이렇게 나눈 관점으로 프로그램을 보면 보다 UI와 프론트엔드 중심으로 프로그램의 구조를 이해할 수 있다.
○ View
사용자의 입력과 결과 출력을 담당하는 계층이다. 이 계층에서 사용자는 데이터를 요청할 수 있고 요청받은 데이터를 확인할 수 있다. 다시 말해 사용자에게 직접적으로 보여지는 화면을 의미한다. 타임리프로 구현하고자 하는 것이 바로 View 계층이다.
○ Model
데이터를 처리하는 모든 시스템과 로직을 담당하는 계층이다.
○ Controller
View와 Model을 서로 연결시키는 계층이다. View에서 받은 요청은 Controller를 통해 Model로 전달되고, Model에서 내놓은 결과값은 Contorller를 통해 View로 전달되어 사용자에게 보여진다.
서버가 클라이언트에게 전달하는 정보는 여러가지가 있다. 이 때 중요한 것은 클라이언트가 필요로 하는 정보만 줘야 하며, 클라이언트에게 보여지거나 외부에 노출되면 곤란한 정보에 대해서는 감춰야 한다는 점이다. 그렇다고 해서 모든 경우에 대응하는 엔티티(Entity)를 만들기에는 비효율적이다. 그래서 등장한 개념이 DTO이다.
□ DTO (Data Transfer Object)
DTO란 오로지 데이터 전송을 목적으로만 설계된 객체를 의미한다. DTO에는 엔티티가 담고 있는 정보들 중에서 전송에 필요한 데이터들만 담고 있으며 전달되어서는 안되는 정보들은 담지 않고 있다. 정보를 전달할 때에는 엔티티 자체를 전달하는 것이 아니라 이렇게해서 생성된 DTO를 보내면 된다.
DTO를 사용했을 때의 장점은 다음과 같다.
○ 보안이 향상된다.
민감한 정보를 담고 있는 엔티티의 경우, 민감한 정보만 빼고 필요한 정보만 보낼 수 있기 때문이다. 또한 엔티티 전체를 공개하게 되면 비즈니스 로직이 유출될 수 있는데, 대신 DTO를 보내면 그러한 위험을 방지할 수 있다.
○ API 설계를 유연하게 할 수 있다.
한 개의 엔티티로도 여러가지 응답에 대응할 수 있다. 여러개의 엔티티를 만드는 대신 여러개의 DTO를 만들면 되기 때문이다.
○ 유지 보수가 쉬워진다.
엔티티가 변경되어도 전체 코드에 큰 영향을 미치지 않는다.
○ 순환 참조 문제를 예방할 수 있다.
DTO와 엔티티는 양방향으로 참조하지 않는다. 그래서 JSON 직렬화가 무한히 벌어지는 순환 참조가 발생하는 것을 막을 수 있다.