프로젝트 생성 및 의존성

빠르게 프로젝트를 만들기 위해 https://start.spring.io/ 에서 다음과 같이 설정한 뒤 생성했다.
초기 개발에 필요한 의존성은 아래와 같다.
// build.gradle
...
dependencies {
// Spring Boot
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// JPA
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// Database
runtimeOnly 'com.h2database:h2'
runtimeOnly 'com.mysql:mysql-connector-j'
// Redis
implementation("org.springframework.boot:spring-boot-starter-data-redis")
// Test
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
docker-compose.yml

다음은 로컬 개발 환경에서 빠르게 개발하기 위한 docker 설정 파일이다. 기본적으로 MySQL과 Redis를 사용하기 때문에 관련 설정을 진행해주었다. 프로젝트 루트에 docker 패키지를 만들고, 여기에 'docker-compose.yml'과 데이터베이스 권한 부여를 위한 'init.sql'도 함께 만들어준다. 여기에 사용된 유저 이름이나 비밀번호는 프로젝트에 맞게 바꿔주면 되겠다.
# docker-compose.yml
version: '3'
services:
mysql:
image: mysql:8.0
container_name: mysql8
restart: always
ports:
- '3306:3306'
environment:
MYSQL_USER: example-user
MYSQL_PASSWORD: example-password
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: example-db
TZ: 'Asia/Seoul'
volumes:
- example-db:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
redis:
image: redis:7.2.4-alpine
container_name: redis7
command: redis-server --port 6379
restart: always
hostname: root
labels:
- 'mode:standalone'
ports:
- '6379:6379'
volumes:
example-db:
# init.sql
CREATE DATABASE IF NOT EXISTS `example-db`;
GRANT ALL PRIVILEGES ON `example-db`.* TO 'example-user'@'%' WITH GRANT OPTION;
USE `example-db`;
이후 컨테이너를 띄운 뒤 확인하면 다음과 같을 것이다.


데이터베이스도 잘 생성되었다.
application.yml
다음은 application.yml 설정이다. 추후 로컬, 개발, 운영 등 여러 환경으로 나눠 관리할 것을 생각해 프로필을 지정했다. 예를 들어 로컬 환경에선 'application-local.yml', 개발 환경에선 'application-dev.yml', 운영 환경에선 'application-prod.yml' 처럼 'application-xxx.yml' 형식으로 이름을 정하면 된다. 또한 보안을 위해 중요한 정보는 프로젝트 루트에 '.env' 파일을 생성해 관리하도록 했다. (여기선 환경변수 설정 과정은 생략한다.)
# application.yml
spring:
profiles:
active: ${PROFILE} # 로컬 환경에선 이곳에 local이 들어감
# application-local.yml
server:
port: 8080
spring:
jackson:
property-naming-strategy: SNAKE_CASE
datasource:
url: jdbc:mysql://localhost:3306/example-db
username: example-user
password: example-password
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: create
properties:
hibernate:
show_sql: true
format_sql: true
⚙️ jackson.property-naming-strategy
해당 옵션은 Jackson 라이브러리를 사용하는 JSON 직렬화/역직렬화 시 프로퍼티 이름 변환 전략을 설정한다. 'SNAKE_CASE'는 Java 객체의 속성명이 'CamelCase'일 때 JSON 직렬화 시 Snake_case로, 역직렬화 시 반대로 처리된다. 아래는 예시이다.
public record UserDto(
String userName,
String createdAt
) {
}
// <->
{
"user_name": "name",
"created_at": "2024-12-05T00:00:00"
}
⚙️ hibernate.ddl-auto
JPA에서 애플리케이션 시작 시 데이터베이스 테이블을 어떻게 관리할지 정의하는 설정이다. none, validate, update, create, create-drop 옵션이 있다. 실제 운영 환경에서는 이를 사용하면 안 된다. 지금은 초기 설정 단계이므로 create로 했지만, 이후 flyway를 통해 해당 옵션을 제거할 것이다. 참고로 create 옵션은 애플리케이션을 시작할 때마다 테이블을 생성하고, 기존 데이터는 삭제한다.
Health Check
본격적으로 유저 도메인을 추가하기 전, 서버 상태를 확인하는 간단한 헬스 체크 API를 하나 만들었다. 애플리케이션 상태를 확인하는 것이 가장 큰 목적이다. 이후 배포시 선행 조건으로도 적용될 것이며, 시스템의 상태를 지속적으로 모니터링할 수 있도록 한다.
@RestController
@RequestMapping("/api/v1/health")
public class HealthController {
@GetMapping
public String healthCheck() {
return "ok";
}
}
Postman으로 확인해보자.

BaseTimeEntity
데이터의 생성 및 수정 시간을 관리하기 위해 추상 클래스인 BaseTimeEntity를 사용했다. 이를 상속받은 엔티티는 특별한 처리를 하지 않아도 생성/수정 시간이 자동으로 관리된다. 즉, 모든 엔티티에서 공통으로 사용하는 시간 정보를 포함한다. 아래 게시글을 참고하면 된다.
https://jnsodevelop.tistory.com/45
[JPA] JPA Auditing, BaseTimeEntity
1️⃣ 개요요즘 캡스톤 디자인 발표 전 막바지 작업을 한다고 블로그 관리를 거의 못했다.대신 그동안 프로젝트를 하며 공부한 내용, 알게된 내용이 굉장히 많았고, 모두 블로그에 올릴 생각이
jnsodevelop.tistory.com
다만 이번엔 'JpaConfig'라는 설정 클래스를 만들어주었다. @Configuration을 통해 설정 클래스임을 명시한다.
@Configuration
@EnableJpaAuditing
public class JpaConfig {
}
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseTimeEntity {
@CreatedDate
@Column(name = "created_at", nullable = false, updatable = false)
private LocalDateTime createdAt;
@LastModifiedDate
@Column(name = "updated_at", nullable = false)
private LocalDateTime updatedAt;
}
다음 글부턴 본격적으로 인증/인가 및 공통 기능들을 개발해보도록 하겠다.
Spring Boilerplate 시리즈 (1) - 프로젝트 개요 및 요구 사항 분석
Spring Boilerplate 시리즈 (2) - 프로젝트 세팅
Spring Boilerplate 시리즈 (3) - 유저 도메인 추가
프로젝트 생성 및 의존성

빠르게 프로젝트를 만들기 위해 https://start.spring.io/ 에서 다음과 같이 설정한 뒤 생성했다.
초기 개발에 필요한 의존성은 아래와 같다.
// build.gradle
...
dependencies {
// Spring Boot
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// JPA
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// Database
runtimeOnly 'com.h2database:h2'
runtimeOnly 'com.mysql:mysql-connector-j'
// Redis
implementation("org.springframework.boot:spring-boot-starter-data-redis")
// Test
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
docker-compose.yml

다음은 로컬 개발 환경에서 빠르게 개발하기 위한 docker 설정 파일이다. 기본적으로 MySQL과 Redis를 사용하기 때문에 관련 설정을 진행해주었다. 프로젝트 루트에 docker 패키지를 만들고, 여기에 'docker-compose.yml'과 데이터베이스 권한 부여를 위한 'init.sql'도 함께 만들어준다. 여기에 사용된 유저 이름이나 비밀번호는 프로젝트에 맞게 바꿔주면 되겠다.
# docker-compose.yml
version: '3'
services:
mysql:
image: mysql:8.0
container_name: mysql8
restart: always
ports:
- '3306:3306'
environment:
MYSQL_USER: example-user
MYSQL_PASSWORD: example-password
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: example-db
TZ: 'Asia/Seoul'
volumes:
- example-db:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
redis:
image: redis:7.2.4-alpine
container_name: redis7
command: redis-server --port 6379
restart: always
hostname: root
labels:
- 'mode:standalone'
ports:
- '6379:6379'
volumes:
example-db:
# init.sql
CREATE DATABASE IF NOT EXISTS `example-db`;
GRANT ALL PRIVILEGES ON `example-db`.* TO 'example-user'@'%' WITH GRANT OPTION;
USE `example-db`;
이후 컨테이너를 띄운 뒤 확인하면 다음과 같을 것이다.


데이터베이스도 잘 생성되었다.
application.yml
다음은 application.yml 설정이다. 추후 로컬, 개발, 운영 등 여러 환경으로 나눠 관리할 것을 생각해 프로필을 지정했다. 예를 들어 로컬 환경에선 'application-local.yml', 개발 환경에선 'application-dev.yml', 운영 환경에선 'application-prod.yml' 처럼 'application-xxx.yml' 형식으로 이름을 정하면 된다. 또한 보안을 위해 중요한 정보는 프로젝트 루트에 '.env' 파일을 생성해 관리하도록 했다. (여기선 환경변수 설정 과정은 생략한다.)
# application.yml
spring:
profiles:
active: ${PROFILE} # 로컬 환경에선 이곳에 local이 들어감
# application-local.yml
server:
port: 8080
spring:
jackson:
property-naming-strategy: SNAKE_CASE
datasource:
url: jdbc:mysql://localhost:3306/example-db
username: example-user
password: example-password
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: create
properties:
hibernate:
show_sql: true
format_sql: true
⚙️ jackson.property-naming-strategy
해당 옵션은 Jackson 라이브러리를 사용하는 JSON 직렬화/역직렬화 시 프로퍼티 이름 변환 전략을 설정한다. 'SNAKE_CASE'는 Java 객체의 속성명이 'CamelCase'일 때 JSON 직렬화 시 Snake_case로, 역직렬화 시 반대로 처리된다. 아래는 예시이다.
public record UserDto(
String userName,
String createdAt
) {
}
// <->
{
"user_name": "name",
"created_at": "2024-12-05T00:00:00"
}
⚙️ hibernate.ddl-auto
JPA에서 애플리케이션 시작 시 데이터베이스 테이블을 어떻게 관리할지 정의하는 설정이다. none, validate, update, create, create-drop 옵션이 있다. 실제 운영 환경에서는 이를 사용하면 안 된다. 지금은 초기 설정 단계이므로 create로 했지만, 이후 flyway를 통해 해당 옵션을 제거할 것이다. 참고로 create 옵션은 애플리케이션을 시작할 때마다 테이블을 생성하고, 기존 데이터는 삭제한다.
Health Check
본격적으로 유저 도메인을 추가하기 전, 서버 상태를 확인하는 간단한 헬스 체크 API를 하나 만들었다. 애플리케이션 상태를 확인하는 것이 가장 큰 목적이다. 이후 배포시 선행 조건으로도 적용될 것이며, 시스템의 상태를 지속적으로 모니터링할 수 있도록 한다.
@RestController
@RequestMapping("/api/v1/health")
public class HealthController {
@GetMapping
public String healthCheck() {
return "ok";
}
}
Postman으로 확인해보자.

BaseTimeEntity
데이터의 생성 및 수정 시간을 관리하기 위해 추상 클래스인 BaseTimeEntity를 사용했다. 이를 상속받은 엔티티는 특별한 처리를 하지 않아도 생성/수정 시간이 자동으로 관리된다. 즉, 모든 엔티티에서 공통으로 사용하는 시간 정보를 포함한다. 아래 게시글을 참고하면 된다.
https://jnsodevelop.tistory.com/45
[JPA] JPA Auditing, BaseTimeEntity
1️⃣ 개요요즘 캡스톤 디자인 발표 전 막바지 작업을 한다고 블로그 관리를 거의 못했다.대신 그동안 프로젝트를 하며 공부한 내용, 알게된 내용이 굉장히 많았고, 모두 블로그에 올릴 생각이
jnsodevelop.tistory.com
다만 이번엔 'JpaConfig'라는 설정 클래스를 만들어주었다. @Configuration을 통해 설정 클래스임을 명시한다.
@Configuration
@EnableJpaAuditing
public class JpaConfig {
}
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseTimeEntity {
@CreatedDate
@Column(name = "created_at", nullable = false, updatable = false)
private LocalDateTime createdAt;
@LastModifiedDate
@Column(name = "updated_at", nullable = false)
private LocalDateTime updatedAt;
}
다음 글부턴 본격적으로 인증/인가 및 공통 기능들을 개발해보도록 하겠다.
Spring Boilerplate 시리즈 (1) - 프로젝트 개요 및 요구 사항 분석
Spring Boilerplate 시리즈 (2) - 프로젝트 세팅
Spring Boilerplate 시리즈 (3) - 유저 도메인 추가