Layered Architecture — *책임을 층으로 나누기*
Layered Architecture — *책임을 층으로 나누기*
🎯 이 lesson 을 읽고 나면
이 lesson 을 다 읽고 나면 아래 3가지를 자신 있게 할 수 있습니다.
- ▸✅ Controller → Service → Repository 3계층 책임 분리
- ▸✅ @Transactional 이 적용되어야 할 정확한 위치
- ▸✅ DTO ↔ Entity 변환의 책임을 누가 가져야 하는지
학습 목표를 체크리스트로 두고 다 답할 수 있게 되면 lesson 을 닫으세요.
왜 *3 계층* 으로 나누나
핵심 한 줄
Spring 백엔드는 보통 Controller → Service → Repository 3계층으로 코드를 나눕니다. 각 계층이 명확한 책임 을 갖게 해서 유지보수 가능한 코드 를 만드는 표준.
각 계층의 역할
Controller: HTTP 의 입출구. 요청 받기·검증·응답 만들기. 비즈니스 로직 X.
Service: 비즈니스 로직의 중심. 트랜잭션 단위. 여러 Repository·외부 API 조합.
Repository: DB 와의 대화. 쿼리만. 비즈니스 판단 X.
왜 이렇게 나누나
1. 책임 분리: 각 계층이 한 가지만 잘 합니다. Controller 가 DB 쿼리도 하면 뒤죽박죽.
2. 테스트 용이: Service 테스트할 때 진짜 Controller·Repository 없이 단위 테스트 가능. Mock 으로 대체.
3. 변경 격리: HTTP 가 GraphQL 로 바뀌어도 Controller 만 수정. Service·Repository 그대로.
4. 트랜잭션 경계: @Transactional 을 Service 메서드 에만 붙이는 게 표준. Controller·Repository 에 붙이면 애매한 경계.
실전 예시
Controller 는 얇고, Service 는 비즈니스 규칙으로 두껍고, Repository 는 DB 접근만 — 깔끔한 구조.
DTO — 계층 간 데이터 운반 객체
각 계층은 같은 객체 를 직접 주고받지 않습니다. DTO (Data Transfer Object) 로 변환해서 전달.
- ▸CreateUserDto — 요청 본문
- ▸User — JPA 엔티티 (DB 매핑)
- ▸UserDto — 응답 객체
왜 분리하나?
- ▸엔티티의 내부 구조 가 외부에 노출 안 됨 (보안·캡슐화)
- ▸비밀번호 같은 민감한 필드 를 응답에서 자연스럽게 제외
- ▸API 변경이 엔티티에 영향 X (느슨한 결합)
Java 14+ 의 record 가 DTO 만들기에 환상적입니다:
흔한 안티 패턴
1. Controller 가 비즈니스 로직 함: 트랜잭션 깨짐·재사용 X
2. Service 가 HttpServletRequest 받음: HTTP 의존 으로 테스트·재사용 어려움
3. Repository 에 비즈니스 규칙: 같은 쿼리 다른 곳에 또 작성됨
4. 엔티티를 그대로 응답: 비밀번호 노출·내부 구조 외부 결합
한 번 정리
3 계층은 Spring 표준. 각 계층이 한 가지만 잘 하도록 책임을 나눕니다. DTO 로 계층 사이 데이터 운반 하면 결합도가 낮아집니다.
🤖 AI 에게 이렇게 요청해보세요
이 lesson 의 개념을 알면 AI 에게 구체적으로 지시할 수 있습니다. 막연한 "고쳐줘" 가 아니라 어휘를 가진 요청 — 그게 토큰 절약의 출발점입니다.
- ▸"이 Spring Boot 코드에 Layered Architecture — 책임을 층으로 나누기 패턴을 적용해줘"
- ▸"Layered Architecture — 책임을 층으로 나누기 관련 @SpringBootTest 통합 테스트 작성해줘"
- ▸"실무에서 Layered Architecture — 책임을 층으로 나누기 사용 시 주의할 함정 3가지 알려줘"
왜 이게 토큰을 줄이나
개념을 모를 땐 AI 답변을 받고도 "그게 뭐예요?" 를 다시 물어야 합니다. 그 "다시 물음" 이 토큰을 잡아먹습니다. 개념 한 번 익혀두면 대화가 한 번에 끝납니다.