백엔드 기초 재정비/스프링 계층 구조 이해

Controller / Service / Repository 역할 정리

namerong 2026. 2. 25. 23:26

 

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는 데이터를 저장한다.

계층 분리는 단순한 구조 분리가 아니라
책임 분리와 변경 최소화를 위한 설계 원칙이다.

각 계층이 자신의 역할만 수행할 때
유지보수 가능하고 확장 가능한 시스템이 만들어진다.