2.8 KiB
2.8 KiB
ADR-001: Spring MVC 아키텍처 경계 및 계약 정의
Context
runtime-role-matrix-live 프로젝트는 Spring Boot 기반 REST API 서버로 역할 기반 접근 제어(RBAC)를 구현한다. 레이어 간 책임 분담, 오류 처리 계약, 트랜잭션 범위가 명시적으로 정의되어 있지 않아 일관성 없는 구현이 발생할 위험이 있다.
Decision
1. 레이어 경계 정의
| 레이어 | 책임 |
|---|---|
| Controller | HTTP 요청/응답, 입력 검증, DTO 변환, HTTP 상태 코드 결정. 트랜잭션 경계 없음 |
| Service | 비즈니스 로직, 도메인 객체 조작, @Transactional 선언적 트랜잭션, BusinessException 발생 |
| Repository | 데이터 접근(JPA), 쿼리 실행, Entity 변환. 순수 데이터 조작만 수행 |
2. 오류 계약 (RFC 7807 Problem Details)
{
"type": "https://api.runtimematrix.com/errors/role-not-found",
"title": "역할을 찾을 수 없습니다",
"status": 404,
"detail": "ID가 'admin'인 역할이 존재하지 않습니다.",
"instance": "/api/v1/roles/admin",
"timestamp": "2026-07-14T15:22:00Z",
"traceId": "abc123def456"
}
예외 계층: RuntimeException → BusinessException(추상) → RoleNotFoundException, RoleAlreadyExistsException
HTTP 상태 매핑:
| 예외 | 상태 |
|---|---|
| ValidationException | 400 |
| BusinessException | 400/409 |
| RoleNotFoundException | 404 |
| PermissionDeniedException | 403 |
| InternalServerException | 500 |
3. 트랜잭션 경계
| 규칙 | 설명 |
|---|---|
| 시작점 | Service Layer public 메서드 |
| 전파 | REQUIRED (기본값) |
| 읽기 전용 | SELECT-only 메서드에 readOnly=true |
| 격리 수준 | READ_COMMITTED |
| 롤백 | RuntimeException, BusinessException → Yes |
4. 의존성 규칙
| From → To | 허용 |
|---|---|
| Controller → Service | ✅ |
| Controller → Repository | ❌ |
| Service → Repository | ✅ |
| Service → Domain | ✅ |
| Repository → Service | ❌ |
5. 패키지 구조
com.runtimematrix
├── controller/dto # Request/Response DTO
├── service/command # Command 객체
├── repository # JPA Repository
├── domain/model # 도메인 객체
├── domain/exception # 도메인 예외
└── config # Spring Configuration
Consequences
긍정: 레이어별 책임 명확, 일관된 오류 응답, 데이터 일관성 보장, 테스트 용이성 향상
부정: 기존 코드 수정 필요, 추가 DTO/Command 클래스 필요