개요
개발 공부를 하면서 프로젝트를 처음 시작할 때 무엇부터 해야할지 막막했던 경험이 있을 것이고, 나 또한 그랬다. 만약 어디서부터 어떻게 시작해야할지 안다고 하더라도, 이를 처음부터 구현하기엔 꽤 많은 시간과 노력이 들어간다고 생각한다. 나는 이런 번거로움을 줄이고 시간을 절약하기 위해 간단한 보일러플레이트 프로젝트를 시작해보려 한다.
수많은 애플리케이션들은 그 성격에 따라 요구사항도 천차만별일 것이고, 필요한 기능도 모두 다르겠지만, 자주 사용하거나 대부분의 상황에서 공통으로 필요한 기능들이 있다. 예를 들어 기본적인 유저 관리 기능, 로깅이나 응답 형식, 예외 처리 등 말이다.
이러한 것들을 템플릿으로 만들어 효율적으로 개발하고 비즈니스 로직에 집중하기 위해, 다시 한번 초기 세팅부터 배포까지 복습하자는 목표를 갖고 프로젝트를 시작하게 되었다.
Boilerplate Code
'보일러플레이트 코드'란 SW개발에서 특정 기능을 구현하거나 프로젝트를 시작하기 위해 필요한 기본적인 코드 구조나 설정을 말한다. 위에서 언급했듯 자주 반복되거나 대부분의 애플리케이션에서 필요한 코드 작성 시간을 줄이기 위해 미리 준비된 템플릿인 것이다.
- 반복되는 코드 : 프로젝트마다 비슷한 형태로 제공되는 기능, 코드 (초기 설정, 인증 등)
- 재사용 가능 : 다양한 프로젝트에서 동일한 패턴이나 구조를 바로 사용할 수 있도록 설계
- 시간 절약 : 초기 설정 및 공통 작업을 자동화하여 개발 속도 향상
붕어빵을 예로 들자면 팥, 슈크림, 초코 등 여러 종류가 있을 것이다. 하지만 이들 모두 같은 반죽, 붕어빵 틀을 통해 만들어진다. 이를 미리 준비하고 붕어빵을 굽기만 한다면 효율적으로 관리할 수 있다. 즉, 붕어빵은 애플리케이션이 되고 보일러플레이트 코드는 반죽과 틀 등과 같은 역할을 하게 된다.
개발 환경
- Java 17
- Spring Boot 3.x
- Gradle 8.x
- MySQL 8.x
- Redis 7.x
- Docker
- AWS
필요 기능
프로젝트를 시작하기 앞서 어떤 기능이 필요하고, 무엇을 구현할지부터 시작한다. 큰 틀은 아래와 같다.
- 프로젝트 설정
- 유저 인증/인가
- 응답 형식
- 예외 처리
- 로깅
- 배포 설정
- 유틸리티
보면 알겠지만 공통적으로 자주 사용되는 것들이다. 그렇다고 너무 많은 것들을 구현하진 않을 것이다. (물론 위의 것들만 해도 많다요) 같은 보일러플레이트를 적용하는 프로젝트여도 각각 성격이 다를 수 있기에 최대한 유연하게 사용할 수 있도록 하기 위함이다.
아래는 각 부분에 대한 간단한 설명이다. 보다 자세한 설명과 과정은 이후 글에서 확인하면 될 것 같다.
유저 인증/인가
기본적으로 카카오, 구글 등 OAuth 2.0 기반 소셜 로그인과 JWT 방식을 적용하려고 한다. 요즘 애플리케이션들은 대부분 소셜 로그인을 지원한다. 그 이유를 생각하면 사용자 편의성 증대, 보안 향상, 개발 및 유지보수 비용 절감 등이 있을 것이다. 다만 고민 중인건 자체 로그인이다. 자체 서비스에서 비밀번호 등 유저 데이터를 직접 다루면 관리 포인트가 늘어나고, 나 또한 소셜 로그인을 주로 사용하기 때문이다. 좀 더 고민해봐야겠지만, 우선은 보일러플레이트이기 때문에 자체 로그인 + 소셜 로그인 모두 구현해볼 생각이다.
이와 더불어 사용자 인증 방식으론 JWT를 채택했다. 이후 자세히 다루겠지만, 무상태 인증 방식과 분산 환경에서의 확장성을 생각할 때 보안과 유연성을 동시에 만족하는 데엔 JWT가 적합하다고 생각했기 때문이다. 결론적으로 OAuth2 + JWT 방식을 구현할 계획이다. (카카오, 구글)
응답 형식
공통 응답 형식에 대한 고민은 꽤 오래 전부터 해왔다. 그럼 이를 왜 사용할까? 공통 응답 형식을 사용하면 클라이언트 측에서 공통 방식으로 데이터를 처리할 수 있기 때문에 관리가 수월해진다. 또한 API 응답 구조를 예측해 응답 처리 로직을 재사용하거나 간소화할 수 있다. 이외에도 확장성이나 디버깅 등을 생각하면 공통 응답 형식을 사용할 때 이점이 분명히 존재한다고 생각한다. 가령 아래와 같은 구조일 것인다.
{
"success": true,
"message": "Request processed successfully",
"data": ...
}
로깅
로깅은 SW 개발을 넘어 운영에서도 필수적인 요소로, 동작 상태를 기록하고 이를 추적해 여러 문제를 해결하고 예방할 수 있다. 이전엔 로깅에 대해 크게 생각하지 않았지만, 시간이 지날수록 그 중요성이 크다는 것을 느낀다. 따라서 공통 로깅 형식을 정의하고, 이를 파일로 저장하는 등 관리하는 것까지 생각중이다. 가능하다면 애플리케이션 레벨에서의 로그 뿐만 아니라, 매트릭 데이터까지 수집하고 분석하는 것까지 시도해보려 한다.
배포
AWS를 통해 간단하게 배포할 생각이다. 또한 무중단 배포 방식 중 하나인 'blue/green' 방식을 채택한다. 아직 인프라 관련 지식이 많이 부족하다고 판단했고, 다시 배포하는 과정을 통해 복습도 하면서 자주 사용할 배포 스크립트 등도 만들어볼 생각이다. 아직 프리티어 기간이 조금 남은 것 같은데 빨리 써먹어야겠다. (사실 25 크레딧 더 있다.)
패키지 구조
DDD 4-Layered 아키텍처를 채택했다. 그동안 MVC 패턴을 주로 사용했었는데, 비즈니스 로직을 분리할 때 어려웠던 적이 꽤 많았다. 또한 외부 의존성 분리시 어떤 레이어에 속해야할지 판단하기 애매한 클래스들도 많았다. 따라서 확장성이 높고 유지보수가 용이한 DDD를 선택하였다. 이는 MSA나 멀티 모듈 프로젝트에서도 MVC보다 쉽게 적용할 수 있겠다는 생각이 들었고, 복잡한 비즈니스 요구사항을 명확하게 구조화할 수 있다는 점에서 장점이 있는 것 같다. 예를 들어 유저 도메인의 패키지 구조는 아래와 같다.
- user
- application
- domain
- infrastructure
- presentation
- 타 도메인
[시리즈 보러가기]
Spring Boilerplate 시리즈 (1) - 프로젝트 개요 및 요구 사항 분석
Spring Boilerplate 시리즈 (2) - 프로젝트 세팅
Spring Boilerplate 시리즈 (3) - 유저 도메인 추가