2022-12-19-TIL
2022-12-19-TIL
Today I Learned
Layered Architecture
계층형 아키텍처는 애플리케이션을 역할별 층으로 나누는 구조다. Martin Fowler는 가장 흔한 형태로 프레젠테이션(HTTP 요청 처리와 화면), 도메인(검증과 계산 같은 업무 로직), 데이터 소스(DB나 외부 서비스 접근) 세 층을 든다. 층을 나누는 가장 큰 이유는 세 주제를 비교적 독립적으로 생각할 수 있게 해서 한 번에 신경 쓸 범위를 줄이는 것이다. 같은 도메인 로직을 웹과 API 같은 여러 프레젠테이션이 공유할 수 있고, 층 경계가 테스트 경계가 되기도 한다(PresentationDomainDataLayering).
의존성은 위에서 아래로 흐른다. 프레젠테이션은 도메인에, 도메인은 데이터 소스에 의존한다. Fowler는 여기서 한 단계 더 나아가 도메인과 데이터 소스 사이에 매퍼를 두어 도메인이 데이터 소스를 모르게 만드는 변형도 소개하는데, 이것이 헥사고날 아키텍처로 이어진다. 첫 번째 링크의 클린 아키텍처 글도 같은 방향이다.
Spring 애플리케이션에서는 이 세 층이 보통 다음처럼 대응된다.
| 층 | Spring에서의 역할 | 대표 애노테이션 |
|---|---|---|
| 프레젠테이션 | 요청을 받고 응답을 만든다 | @RestController |
| 도메인(서비스) | 업무 로직과 트랜잭션 경계 | @Service, @Transactional |
| 데이터 접근 | DB 조회와 저장 | @Repository |
자주 하는 실수는 컨트롤러가 리포지토리를 직접 부르거나, 엔티티를 그대로 응답으로 내보내서 프레젠테이션과 데이터 층이 붙어 버리는 것이다.
- https://www.baeldung.com/spring-boot-clean-architecture
- https://medium.com/swlh/designing-a-multi-layered-architecture-for-building-restful-web-services-with-spring-boot-and-a12ef85b77c9
Spring Boot Architecture
Spring Boot 문서는 코드 구조에 대해 강제하는 것이 없다고 하면서 몇 가지를 권한다. 패키지 선언이 없는 기본 패키지는 쓰지 않는다. @SpringBootApplication이 붙은 메인 클래스는 다른 클래스보다 위의 루트 패키지에 둔다. 이 애노테이션이 컴포넌트 스캔과 @Entity 탐색의 기준 패키지가 되기 때문이다(Spring Boot: Structuring Your Code).
문서의 예시 구조는 계층별이 아니라 기능별로 패키지를 나눈다.
1
2
3
4
5
6
7
8
9
10
11
12
com.example.myapplication
+- MyApplication.java
+- customer
| +- Customer.java
| +- CustomerController.java
| +- CustomerService.java
| +- CustomerRepository.java
+- order
+- Order.java
+- OrderController.java
+- OrderService.java
+- OrderRepository.java
controller, service, repository 패키지로 나누는 계층별 구조와 비교하면, 기능별 구조는 한 기능을 고칠 때 한 패키지 안에서 끝나는 경우가 많다. 계층은 패키지가 아니라 클래스 단위로 여전히 나뉘어 있으므로 위의 계층형 아키텍처와 충돌하지 않는다.
- https://www.javatpoint.com/spring-boot-architecture
- https://www.geeksforgeeks.org/spring-boot-architecture/
댓글
아직 댓글이 없습니다