1. Controller 역할
Controller는 “입구” 역할을 담당한다.
하는 일
- HTTP 요청 받기
- URL, PathVariable, QueryString, RequestBody 파싱
- 로그인 사용자 확인
- 요청 값 기본 검증(필수값, 형식)
- Service 호출
- HTTP 응답 반환
즉, 웹 계층과 직접 연결된 부분이다.
하면 안 되는 일
- 비즈니스 정책 판단
- 트랜잭션 처리
- DB 직접 접근
- Repository 직접 호출
- 복잡한 도메인 로직 작성
Controller에서 DB를 직접 호출하면
웹 요청 처리와 비즈니스 로직, 데이터 접근이 한 계층에 섞이게 된다.
이 경우
- 책임이 분리되지 않는다.
- 변경에 취약해진다.
- 테스트가 어려워진다.
- API 외의 다른 인터페이스(배치, 이벤트 등)에서 재사용이 어렵다.
2. Service 역할
Service는 시스템의 “두뇌” 역할을 한다.
하는 일
- 비즈니스 정책 판단 (가능/불가)
- 상태 변경
- 트랜잭션 관리
- 여러 Repository 조합
- 이벤트 발행
- 외부 API 호출
- 캐시 사용
- 도메인 규칙 적용
예시
- 이미 구독 중이면 예외 발생
- 재고 부족 시 주문 불가
- 환불 시 주문 상태 변경
- 결제 성공 시 구독 ACTIVE로 변경
Service는 도메인 규칙과 정책을 담당한다.
3. Repository 역할
Repository는 DB 접근만 담당한다.
하는 일
- DB 조회
- DB 저장
- SQL 실행
- 영속성 관리
하면 안 되는 일
- 정책 판단
- 상태 전이 결정
- 복잡한 비즈니스 로직
Repository는 데이터 입출력 계층이다.
“왜 저장하는가”는 Service가 결정하고,
“어떻게 저장하는가”는 Repository가 담당한다.
4. 계층 분리가 필요한 이유
1) 책임 분리 (Single Responsibility)
Controller가 정책까지 판단하면
→ 웹 방식이 바뀔 때마다 로직을 수정해야 한다.
Service가 DB까지 직접 처리하면
→ DB가 바뀌면 정책 코드까지 수정해야 한다.
책임이 분리되어야 각 변경이 서로 영향을 덜 준다.
2) 변경에 강한 구조
예시 상황
- DB를 MySQL → MongoDB로 변경
- REST → GraphQL로 변경
- 동일 로직을 배치나 이벤트 기반 처리에서도 사용
계층이 분리되어 있다면
- DB 변경은 Repository 수정으로 제한된다.
- API 변경은 Controller 수정으로 제한된다.
- Service 로직은 그대로 재사용 가능하다.
즉, 수정 범위가 최소화된다.
3) 테스트 용이성
- Service는 Controller 없이도 단위 테스트 가능
- Repository는 Mock으로 대체 가능
- 비즈니스 로직을 독립적으로 검증 가능
이는 유지보수 비용 감소로 이어진다.
5. 잘못된 설계 vs 개선 설계
잘못된 구조
Controller {
DB 조회
정책 판단
저장
응답 반환
}
문제점
- 모든 책임이 한 곳에 몰림
- 코드가 비대해짐
- 수정 시 영향 범위 큼
- 테스트 어려움
- 재사용 불가
개선된 구조
Controller → Service → Repository → DB
- Controller = 요청/응답 담당
- Service = 정책 및 상태 전이 담당
- Repository = DB 접근 담당
각 계층이 독립적으로 동작한다.
6. 실무 관점에서의 Service 중요성
실무에서 Service는 단순 중간 계층이 아니다.
다음과 같은 책임을 가진다.
- 트랜잭션 경계 설정
- 도메인 이벤트 발행
- 외부 결제 API 호출
- 캐시 처리
- 동시성 제어
- 상태 전이 관리
따라서 Service는 시스템의 핵심 두뇌라고 볼 수 있다.
최종 정리
Controller는 요청을 받고,
Service는 정책을 실행하며,
Repository는 데이터를 저장한다.
계층 분리는 단순한 구조 분리가 아니라
책임 분리와 변경 최소화를 위한 설계 원칙이다.
각 계층이 자신의 역할만 수행할 때
유지보수 가능하고 확장 가능한 시스템이 만들어진다.
'백엔드 기초 재정비 > 스프링 계층 구조 이해' 카테고리의 다른 글
| 트랜잭션 실패 사례와 롤백 필요성 정리 (0) | 2026.03.03 |
|---|---|
| 트랜잭션(Transaction) 개념과 주문 생성 예제 (0) | 2026.03.02 |
| 로그인 API가 하는 일과 요청 → 응답 흐름 정리 (0) | 2026.02.27 |
| DTO vs Entity 정리 (0) | 2026.02.26 |