# ADR-001: Controller-Service-Repository 경계 정의 ## Context 본 프로젝트(runtime-role-smoke-202607140500)는 Spring Boot 기반의 역할 관리 시스템이다. 다층 아키텍처에서 각 계층의 책임과 의존성 방향을 명확히 정의하여: - 코드 유지보수성 향상 - 단위 테스트 용이성 확보 - 계층 간 결합도 최소화 를 목적으로 한다. ## Decision ### 1. Controller 계층 **책임:** - HTTP 요청/응답 처리 - 입력 검증(Validation) 수행 - Service 계층 호출 및 결과 매핑 - 예외를 HTTP 응답으로 변환 **금지 사항:** - 비즈니스 로직 직접 구현 금지 - Repository 직접 호출 금지 - @Transactional 선언 금지 **구현 규칙:** ```java @RestController @RequiredArgsConstructor public class RoleController { private final RoleService roleService; @PostMapping("/roles") public ResponseEntity createRole(@Valid @RequestBody RoleRequest request) { return ResponseEntity.status(HttpStatus.CREATED) .body(roleService.createRole(request)); } } ``` ### 2. Service 계층 **책임:** - 비즈니스 로직 수행 - 트랜잭션 관리 - 도메인 객체 조작 - Repository 호출 및 결과 가공 **금지 사항:** - HTTP 요청/응답 직접 처리 금지 - @RequestBody, @RequestParam 등 HTTP 어노테이션 사용 금지 **구현 규칙:** ```java @Service @RequiredArgsConstructor @Transactional(readOnly = true) public class RoleService { private final RoleRepository roleRepository; @Transactional public RoleResponse createRole(RoleRequest request) { // 비즈니스 로직 Role role = Role.create(request.getName(), request.getDescription()); Role savedRole = roleRepository.save(role); return RoleResponse.from(savedRole); } } ``` ### 3. Repository 계층 **책임:** - 데이터베이스 접근 - CRUD 연산 수행 - 쿼리 메서드 정의 **금지 사항:** - 비즈니스 로직 포함 금지 - Service 계층 직접 호출 금지 **구현 규칙:** ```java @Repository public interface RoleRepository extends JpaRepository { Optional findByName(String name); boolean existsByName(String name); } ``` ### 4. 의존성 방향 ``` Controller → Service → Repository → Domain/Entity ↑ (Domain Event를 통한 역방향 허용) ``` **의존성 규칙:** - 상위 계층은 하위 계층에만 의존 - 동일 계층 간 직접 의존 금지 - Domain 객체는 어떤 계층에도 의존하지 않음 ## Alternatives ### 대안 1: Transactional Script 패턴 - 모든 로직을 Controller에 포함 - 단점: 테스트 어려움, 코드 중복 - 채택하지 않음 ### 대안 2: 도메인 주도 설계(DDD) - Aggregate, Entity, Value Object 세분화 - 단점: 과도한 복잡성, 학습 곡선 높음 - 현재 프로젝트 규모에 과도하여 채택하지 않음 ## Consequences **Positive:** - 각 계층의 책임이 명확하여 코드 가독성 향상 - 단위 테스트 시 Mock 객체 사용 용이 - 향후 MSA 전환 시 서비스 분리 용이 **Negative:** - 간단한 CRUD 연산에도 다중 계층 코드 작성 필요 -初期開発時に多少のオーバーヘッド **Mitigation:** - Lombok, MapStruct 활용으로 보일러플레이트 감소 - 공통 응답/예외 처리基础设施建设