From a6cb3603175ca0f9c220fc365e7e06a0ea4f4c5c Mon Sep 17 00:00:00 2001 From: forge-bot Date: Tue, 14 Jul 2026 05:02:53 +0000 Subject: [PATCH] =?UTF-8?q?Spring=20=EA=B2=BD=EA=B3=84=EC=99=80=20?= =?UTF-8?q?=EA=B3=84=EC=95=BD=20=EC=95=84=ED=82=A4=ED=85=8D=EC=B2=98=20?= =?UTF-8?q?=EC=A0=95=EC=9D=98=20(role-ta-001)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ontroller-service-repository-boundaries.md | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 docs/adr/ADR-001-controller-service-repository-boundaries.md diff --git a/docs/adr/ADR-001-controller-service-repository-boundaries.md b/docs/adr/ADR-001-controller-service-repository-boundaries.md new file mode 100644 index 0000000..af42692 --- /dev/null +++ b/docs/adr/ADR-001-controller-service-repository-boundaries.md @@ -0,0 +1,131 @@ +# 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 활용으로 보일러플레이트 감소 +- 공통 응답/예외 처리基础设施建设