안녕하세요, nive입니다 :)
작년 이맘때쯤, 열심히 개발하고 테스트하던 boot-template를 만들었습니다. 1년이 지난 지금, 새삼 감회가 새롭네요.
1. 그때 그 시절, boot-template
돌이켜보면 당시에는 boot-template의 구조가 꽤 만족스러웠습니다. 하지만 지금 보면... 역시 학습 의지가 불타올랐던 만큼 시행착오도 많았던 것 같습니다.
그때 제가 했던 고민들은 이랬습니다:
- 레거시(eGov + JSP)에서 REST API로의 전환: 공공/SI 프로젝트의 전형적인 구조에서 벗어나기
- 공통 응답과 예외 처리 정리: ControllerAdvice 충돌 해결하며 통일된 에러 처리 구현
- 파일 업로드 모듈화: S3와 Local Storage를 분리한 공통 파일 업로드 개발
- Swagger 적용: API 문서화와 테스트 환경 구축
혼자 고군분투하며 새로운 기술을 습득하던 시간이었죠. "이 정도면 REST API 형태로 개발할 수 있겠다"는 자신감도 생겼고, 테스트용으로 써보면 좋겠다는 생각도 했습니다.
하지만 실제로는 쓰지 못했습니다.
당시에는 "공통 기능을 어떻게 만들까"에 집중했지, "개발자가 비즈니스 로직만 집중할 수 있는 구조"까지는 미처 고민하지 못했습니다.
막상 실무에 적용하려니 이런 질문들이 생겼습니다:
- "인증이 필요한 API는 어떻게 처리하지?"
- "파일 업로드는 만들었는데, 실제 도메인에서 어떻게 연결하지?"
- "예외 처리는 공통화했는데, 비즈니스 예외는 어디서 정의하지?"
대신 그때의 삽질과 고민, 설계 경험은 정말 좋은 양분이 되었습니다.
2. 선배님들의 레거시에서 배운 것들
이전부터 선배님들이 닦아둔 프로젝트들을 보면서 느낀 점이 있습니다.
레거시라고 해서 무조건 나쁜 게 아니라는 것.
명확하게 분리되어 있는 데는 분명한 이유가 있었습니다. Controller - Service - Repository의 계층 분리, 공통 모듈의 독립성, 설정 파일의 체계적 관리...
당시에는 "이렇게 되어 있던" 구조를 그냥 따라 쓰기만 했습니다. 선배님들이 만들어둔 틀 안에서 기능만 추가하면 됐으니까요.
하지만 연차가 쌓이면서 조금씩 달라졌습니다. 반복되는 코드가 보이기 시작했고, 공통 Service나 Util을 만들어가며 "왜 이렇게 구조를 잡았는지"를 체득하기 시작했죠.
"날짜 포맷 변환이 여기저기서 쓰이네? → 공통 Util로 빼자"
"API 응답 형식이 제각각이네? → 공통 Response 객체를 만들자"
"파일 업로드가 계속 필요한데? → 공통 Service로 만들자"
이런 경험들이 조금씩 쌓여서 boot-template에 녹아들었습니다.
그리고 25년도 서비스 회사로 이직한 후, 맨땅에서 직접 플랫폼을 구현하면서 그 깨달음이 더욱 구체화되었습니다.
"아, 그래서 인증 필터를 여기에 둔 거구나."
"공통 모듈을 이렇게 분리해야 순환 참조가 안 생기는구나."
"설정 파일을 profile별로 나눠야 배포가 편하구나."
특히 "신규 기능을 추가할 때 기존 코드를 거의 건드리지 않는 구조"의 가치를 절실히 느꼈습니다.
선배님들의 프로젝트에서는 그냥 Controller-Service-Repository만 추가하면 됐던 게, 제가 맨땅에서 만들 때는 매번 "이거 인증은 어떻게 하지?", "예외 처리는 어디서 하지?" 같은 고민을 해야 했으니까요.
그렇게 boot-template의 경험을 바탕으로, 실제 서비스를 위해 구조를 더욱 구체화하고 개발해 나간 결과가 현재의 nive-api-platform입니다.
"이미 만들어진 구조"를 따라 쓰던 시절 → 공통 기능을 만들며 체득하던 시절 → 직접 플랫폼 구조를 설계하는 시절.
돌이켜보면 자연스러운 성장의 과정이었던 것 같습니다.
3. boot-template vs 현재
boot-template 당시
- "공통 기능을 어떻게 구현할 것인가"에 집중
- REST API 전환 자체가 학습 목표
- 동작하는 코드 만들기에 급급
- 공통 기능은 만들었지만, 어떻게 사용할지는 매번 고민해야 했음
현재
- "개발자가 도메인 로직만 작성하면 되는 구조"를 목표로
- 플랫폼 개발과 운영 경험 축적
- 각 코드의 책임 구분과 명확한 경계 설정
- 개발 외적인 부분(운영, 모니터링, 확장성)까지 고려
- 신규 기능 추가 시 플랫폼 레벨 코드는 건드릴 필요 없는 구조
실제 운영을 하다 보니 자연스럽게 늘어나는 것들이 있었습니다:
- 인증/인가: JWT 기반 Stateless 인증, Role 기반 권한 제어
- 예외 처리: 비즈니스 예외와 시스템 예외의 명확한 분리
- 공통 로직: SMS/Email 인증, Rate Limiting, Logging
- Filter와 Interceptor: 인증 필터, 권한 인터셉터, 접속 로그
유지보수하며 덧대는 코드는 계속 생기기 마련입니다. 하지만 명확한 경계를 나눈다면 조금 더 나은 구조를 만들 수 있지 않을까요?
4. 그래서, nive-api-platform
이런 고민 끝에 탄생한 것이 바로 nive-api-platform입니다.
"미리 만들어진 플랫폼 기능과 Spring Boot 위에서,
개발자는 각 기능별 Controller - Service - Repository만 개발하면 된다."
boot-template에서 어렴풋이 그려봤던 이 구조를 실제 개발에 적용하면서 구체화한 결과물입니다.
구조
nive-platform
├── nive-common # 공통 계약 / Pure Java (Spring 의존성 없음)
├── nive-domain # 도메인 모델 + Repository
├── nive-application # UseCase / Query / Adapter (Web, Batch...)
└── nive-web # Spring Boot 설정 / Security / Filter
- 멀티 모듈을 통한 영역별 구분: 컴파일 타임에 의존성 위반 차단
- 클린 아키텍처 + DDD 개념 적용: Port-Adapter 패턴, UseCase 중심 설계
- 구조적 제약사항 설정: 하위 모듈이 상위 모듈을 의존할 수 없도록 강제
개발자가 집중할 곳
이 플랫폼에서 신규 기능을 추가할 때 개발자가 해야 할 일:
- 도메인 엔티티 추가 (nive-domain)
- UseCase 구현 (nive-application)
- Controller 작성 (nive-application/adapter)
- 끝!!
(혹은 개인이 원하는 서비스의 멀티모듈을 따로 추가 후 활용)
인증? 이미 있습니다.
예외 처리? 통일되어 있습니다.
로깅? 자동으로 됩니다.
Health Check? 기본 제공됩니다.
개발자는 비즈니스 로직에만 집중하면 됩니다.
제공되는 nive-application, nive-web 구조는 가이드일 뿐, 프로젝트 특성에 맞게 얼마든지 수정하거나 확장할 수 있습니다!
정답은 없으니까요 :)
boot-template과의 차이
| 구분 | boot-template | nive-api-platform |
|---|---|---|
| 목적 | REST API 학습 | 프로덕션 레벨 베이스 구축 |
| 관점 | "어떻게 만들까?" | "어떻게 쓰게 할까?" |
| 구조 | 단일 모듈 | 멀티 모듈 (4개 계층) |
| 설계 | 레이어드 아키텍처 | 클린 아키텍처 + DDD |
| 플랫폼 기능 | 일부 구현 (파일 업로드, 예외처리) | 인증/인가/로깅/Health Check 등 완비 |
| 신규 기능 추가 | 매번 플랫폼 연동 고민 필요 | Controller-Service-Repository만 작성 |
| 확장성 | 제한적 | 멀티 서비스/배치/이벤트 대응 |
5. 현재 진행형
private 버전으로 조금씩 개발하며 테스트를 진행했고, 이 구조를 기반으로 실제 프로젝트들에도 적용해보았습니다. 운영하면서 발견한 문제들을 개선하고, 부족한 부분을 채워나가는 과정이 계속되고 있습니다.
실제로 이 구조를 적용한 후 체감한 장점
- 신규 API 개발 속도가 빨라짐 (플랫폼 레벨 고민 제거)
- 인증/권한 누락 같은 실수 방지 (구조적으로 강제)
- 일관된 예외 처리와 로깅 (자동 적용)
- 코드 리뷰 시 비즈니스 로직에만 집중 가능
- 플랫폼 기능 확장 시 비즈니스 로직 모듈과의 격리
(Filter, Interceptor, Security, Config 변경이 application이나 추가 서비스 모듈에 미치는 영향 최소화)
public 버전도 지속적으로 업데이트될 예정이며, 아직 부족한 점이 있을 수 있지만 차근차근 개선해 나갈 계획입니다.
자세한 개발 배경이나 설계 의도는 앞으로 다룰 예정입니다.
일단 boot-template 시리즈를 마무리하고 나면, 본격적으로 nive-api-platform의 이야기를 풀어나갈 수 있을 것 같습니다.
올해도 열심히 개발하고 성과를 내면서, 이런 기록들을 남겨두면 내년에는 또 고민하고 성장했던 제 모습을 확인할 수 있지 않을까요?
boot-template를 만들었던 작년 이맘때의 저는 **"어떻게든 REST API를 만들어보자"**는 열정으로 가득했습니다.
1년이 지난 지금은 **"개발자가 편하게 쓸 수 있는 프로젝트"**를 만드는 것에 집중하고 있습니다.
다음 글에서는 boot-template 시리즈를 마무리하고, 곧 nive-api-platform의 아키텍처를 하나씩 풀어보도록 하겠습니다.
오늘도 읽어주셔서 감사드리고, 좋은 하루 보내시길 바랍니다.
감사합니다 :)
'생각 디버깅' 카테고리의 다른 글
| 곧 끝나가는 2025년을 돌아보며 (2) | 2025.12.30 |
|---|---|
| 2025년을 맞이하며 (1) | 2025.01.10 |