스프링 부트를 통해 Lombok, JPA를 활용한 간다한 CRUD API를 만드는 과정에서 Spring Web Layer에 대해 정확하게 이해하는 것이 큰 도움이 될 것 같아 Spring Web Layer를 공부해보았습니다. 그럼 시작하겠습니다.
웹 어플리케이션을 효과적으로 개발하기 위해서 선배 개발자 분들은 아키텍처란 것에 관심을 가지게 됩니다.
SoC(Separation of Concerns)의 관심사 분리라는 원칙, KISS(Keep It Simple Stupid)라는 간단하고 알기 쉽게 만들라는
원칙을 지키는 것이 아키텍처 디자인을 설계하는데 지켜야 할 기본 원칙이라고 보면 되겠습니다.
다시 말해서, 관심사를 식별하고 어디서 처리해야 할지 결정해야 하며 간단하고 알기 쉽게 만드는 것이다!라고 저는 해석하겠습니다..
웹 어플리케이션의 관심사항
웹 어플리케이션을 만들기 위해 아래와 같은 해결해야 할 관심사항들이 있습니다.
- 사용자의 입력을 처리하고, 올바른 응답을 사용자에게 반환해야 합니다.
- 예외처리 메커니즘을 통해 사용자가 납득 가능한 에러 메시지를 공급해야 합니다.
- 트랜잭션 관리 전략이 필요합니다.
- 인증과 권한 부여를 처리해야 합니다.
- 어플리케이션의 비즈니스 로직을 구현해야 합니다.
- 사용된 데이터 스토리지 및 기타 외부 리소스와의 통신이 필요합니다.
3개의 Layer
스프링에서는 단지 3개의 계층을 통해 이러한 요구사항들을 모두 만족시킬 수 있습니다.
Web Layer
웹 어플리케이션의 최상위에 존재하고 있습니다. 외부 요청인 사용자의 입력을 처리하고, 올바른 응답을 사용자에게 반환하는 역할을 합니다. 또한 다른 레이어에서 발행한 예외도 처리해야 하는데 우리 어플리케이션의 진입점이기 때문입니다. 인증을 관리하고 권한 없는 사용자의 인가를 거부하는 역할을 합니다. 컨트롤러, JSP와 같은 뷰 템플릿 영역이라고 생각하면 되겠습니다.
Service Layer
Web Layer 바로 아래에 존재하는 계층으로 트랜잭션에 대한 경계 역할을 하며 어플리케이션과 인프라 서비스 모두를 포함하고 있습니다. 어플리케이션 서비스는 서비스 계층의 공개 API를 공급하며 트랜잭션의 경계 역할과 응답(승인?)을 책임지고 있습니다. 인프라 서비스는 파일 시스템이나 데이터베이스, 이메일 서버와 같은 외부 리소스와 통신하는 "plumbing code"가 포함되어 있습니다.
Controller와 Dao의 중간영역에서 많이 사용되며 @Transcational, @Service에 사용되는 영역이라고 생각하면 됩니다.
Repository Layer
가장 낮은 계층으로 사용되는 데이터 스토리지 계층과 통신하는 역할입니다. 데이터베이스와 같이 데이터 저장소에 접근하는 영역입니다. ex) DAO
특정 계층에 속하는 구성요소들은 동일한 계층 또는 그 아래에 있는 계층에 속하는 구성 요소를 사용할 수 있습니다.
아래의 사진은 이전에 사용된 클래식한 스프링 Web Layer입니다.
각 계층의 인터페이스를 디자인하고 이 단계로 DTO(Data Transfer Object)와 Domain Model가 생겼습니다.
DTO(Data Transfer Object)
- 단순히 데이터를 저장하는 컨테이너이며 서로 다른 프로세스와 어플리케이션 계층간에 데이터를 전달하는데 사용됩니다.
Domain Model
Domain Service는 작업을 제공하는 상태 비저장 클래스입니다.
Entity로 전체 라이프 사이클 동안 변경되지 않는 개체입니다.
Value Object로 속성이나 사물을 설명합니다.
이제는 DTO와 Domain Model의 의미를 이해하고 각 계층의 인터페이스를 통해 디자인 할 수 있습니다.
- Web Layer는 데이터 전송객체만 처리해야 합니다.
- Service Layer는 데이터 전송 객체를 매소드의 매개변수로 사용하여 도메인 모델 객체를 처리할 수 있습니다. 그리고 데이터 전송 객체만 웹 레이어로 되돌릴 수 있습니다.
- Repository Layer는 엔티티를 매소드 매개변수로 가져올 수 있고 엔티티를 리턴합니다.
왜 데이터 전송 객체만 웹 레이어로 반환할 수 있을까요? entity나 value object를 반환하면 되지 않나요? 데이터 전송 객체는 필요 없을 것 같습니다.
라는 의문이 들수 있습니다.
위와 같은 의문에 다음과 같은 2가지의 이유를 말할 수 있습니다.
첫째, 도메인 모델은 애플리케이션의 내부 모델(데이터베이스의 테이블) 입니다. 이것을 외부에 노출시킨다면 클라이언트는 내부 모델을 알지 못하는 상태에서 사용해야 합니다. DTO를 통해 클라이언트에게 모델을 숨기고 더 사용하기 쉬운 API를 제공할 수 있습니다.
둘째, 도메인 모델이 외부에 노출되게 된다면 도메인 모델을 변경해야 할 때, 도메인 모델에 의존하는 것들을 모두 변경해야 합니다. 그러나 우리가 DTO를 사용한다면 도메인 모델을 손쉽게 변경할 수 있습니다! (DTO는 도메인 모델을 모두 담고 있지 않기때문에)
완성된 Spring Web Layer의 모습
사실 공부하면서 와닿는 부분도 있고 그렇지 않은 부분도 있지만 나중에도 계속해서 보다보면 이해가 되지 않을까 생각하면서 포스팅하였습니다.
혹시 모르는 부분이나 잘못된 부분이 있다면 댓글을 통해 문의해주시면 감사하겠습니다. 감사합니다!
'Spring' 카테고리의 다른 글
Autowire 알아보기 - 1 (0) | 2020.09.27 |
---|---|
AOP를 활용한 Logging 구현 (1) | 2020.08.09 |
SpringBoot - ExceptionHandler (1) | 2020.07.05 |
[토이 프로젝트] IT Article - 1 (0) | 2020.06.28 |
Spring WEB MVC와 HttpMessageConverters (1) | 2020.06.24 |