Springboot 를 사용하여 서버를 개발하기 공통 모듈과 개발 가이드를 제공한다. 본 프로젝트 템플릿은 중/소 규모 백엔드 API 서버 개발에 최적화 되어 있다.
패키지명을 변경하여 사용하여야 한다. 다음에서 "com.vrerv.springboottemplate.server" => "com.mycompany.myproject" 로 변경한다.
- build.gradle
- src/main/java
- src/test/groovy
- src/test/java
최신 리눅스나 Mac OS X 에서 개발할 것을 추천한다. Windows OS 의 경우 10 이상 버전을 사용하고 WSL2 환경에서 개발하는 것을 추천한다. 본 문서에서는 해당 환경에서 작동하는 것을 가정한다. 만약 Windows OS 에서 WSL 을 사용하지 않을 경우 일부 기능이 작동되지 않을 수 있다.
- Sdkman - Java 개발을 위한 소프트웨어를 설치하고 관리한다.
- Java 17 - 코드를 빌드하고 구동한다.
- Git - 소스 코드를 관리한다.
- Docker - 배포용 이미지를 생성하고 로컬에 설치하면 구동한다.
- IntelliJ - 코드를 개발한다. 개발자의 역량에 따라 다른 개발툴을 사용하여도 무난하다.
- MySQL DB - 8.0.32 이상을 로컬에 설치하여, 로컬 개발시 사용한다.
- java 17 설치 - sdkman 으로 설치한다.
~/.sdkman
디렉토리를/opt/sdkman
으로 링크한다. (Windows 의 경우 WSL 사용) 만약 디렉토리를 링크하거나 바꿀수 없거나 다른 곳으로 설정한다면,gradle.properties
안에 jdk 경로를 수동으로 설정해주어야 한다. 해당 파일은 git 에 관리되는 파일로 되어 있으므로 되도록 기존 디렉토리 구조를 따르도록 한다.
sdk install java 17.0.5-amzn
MSSQL - docker 사용
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=P@ssw0rd" -p 1433:1433 -d mcr.microsoft.com/mssql/server:2022-latest
Mac book M1 docker
docker run --cap-add SYS_PTRACE -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=P@ssw0rd" -p 1433:1433 --name sqledge -d mcr.microsoft.com/azure-sql-edge
create database test_db;
use test_db;
create login test_user with password = 'P@ssw0rd';
create user test_user for login test_user;
grant select, insert, update, delete, alter, references on DATABASE::test_db to test_user;
- MySQL 을 local 에 설치한다.
- 로컬 구동을 위한 데이터베이스와 계정을 생성한다.
CREATE DATABASE test_db;
CREATE USER 'test_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'P@ssw0rd';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, INDEX, DROP, ALTER, REFERENCES, CREATE TEMPORARY TABLES, LOCK TABLES ON test_db.* TO 'test_user'@'localhost';
GRANT FILE ON *.* TO 'test_user'@'localhost';
FLUSH PRIVILEGES;
- 프로젝트 폴더의 root (server directory) 를 IntelliJ 에서 오픈한다.
- 기본 JDK 설정이 17이 아니라면 프로젝트 JDK 를 설치된 Java 17 으로 설정한다.
- 설정에서 gradle 검색후 gradle 구동 JDK 를 "Project SDK" 로 설정한다.
빌드:
./gradlew clean buid
구동:
./gradlew bootRun
- src/main/java - Java 소스 코드
- src/main/resources - Java 프로젝트 설정 파일
- src/test/java - Java 테스트 코드
- src/test/resources - Java 테스트 코드 설정 파일
- src/test/http - IntelliJ http client 테스트 파일
- src/test/grovvy - Groovy Spock 테스트 코드
- {basePackagePrefix}.{module}.{layer} - 기본 패키지 구조
- {module} - common(공통), 그외 관련 모듈이름
- {layer}
- domain - 도메인 모델 관련 레이어
- application - 서비스, 비즈니스 로직 레이어
- presentation - 웹 API, UI 레이어
각 레이어는 정확히 DDD(Domain Driven Develop)의 레이어와는 일치하지 않는다. SpringFramework, hibernate, String data JPA 등에 강하게 연결되어 있기 때문이다. 다만, 각 레이어간에 정형화를 통해 개발과정을 단순화하고 일관성을 유지하기 위해 레이어를 정의하였다.
도메인 레이어 <- 애플리케이션 레이어 <- 프레젠테이션 레이어 순으로 의존성이 존재한다. 모듈 간의 호출에서는 presentation 레이어의 Endpoint 로 호출한다.
- entity 와 repository 를 주로 다룬다, DB 설계와 도메인 모델의 기본 룰을 설정한다.
- 비지니스 로직을 수행한다.
- 웹 API, UI 레이어
- Spring controller 등
특정 타입에 대한 클래스명 접미사
Repo
- spring data repositoryService
- 비지니스 로직 수행Endpoint
- 웹 API endpointModel
- DTO or VOMapper
- MapStruct mapper or Java Bean converterConfig
- Spring configuration or any 인프라 설정
- JWT 토큰 인증을 사용한다.
- SpringDoc 이 적용되어 서버의 Swagger UI 로 서버에 존재하는 API 확인할 수 있다.
- API 의 명세는
build
시openapi.json
으로 자동 생성된다.
openapi-generator 를 사용하여 API client project 를 생성할 수 있다. CLI 는 여러가지를 지원함으로 필요한 CLI 를 설치해서 사용한다. 아래는 docker 를 사용한 예이다.
아래 docker 명령으로 API client project 를 생성할 수 있다.(server directory 에서 실행)
-i /local/app/openapi.json
대신에 http://localhost:8080/v3/api-docs
(docker 로 실행시에는 ip가 컨테이너 내부에서 host 를 바라보도록 해야 함) 를 사용할 수도 있다.
export PACKAGE_BASE_NAME=com.vrerv.springboottemplate.server
docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate \
-i /local/app/openapi.json \
-g java --library retrofit2 \
--group-id ${PACKAGE_BASE_NAME} \
--artifact-id api-client-java \
--package-name ${PACKAGE_BASE_NAME}.client \
--api-package ${PACKAGE_BASE_NAME}.client.api \
--model-package ${PACKAGE_BASE_NAME}.client.api.model \
--invoker-package ${PACKAGE_BASE_NAME}.client \
-o /local/api-client-java
javascript api client library 생성은 아래와 같이 하면 된다.
export PACKAGE_BASE_NAME=vrerv.springboottemplate
docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate \
-i /local/app/openapi.json \
-g javascript \
--group-id ${PACKAGE_BASE_NAME} \
--artifact-id api-client-java \
--package-name ${PACKAGE_BASE_NAME}.client \
--api-package ${PACKAGE_BASE_NAME}.client \
--model-package ${PACKAGE_BASE_NAME}.client \
--invoker-package ${PACKAGE_BASE_NAME}.client \
-o /local/api-client-javascript
- 모든
Entity
는Long id
필드를 갖는EntityId
클래스를 상속하여 작성한다. Setter
는 업데이트가 가능한 필드만public
으로 선언한다.
MapStruct
를 사용하여DTO
,Entity
또는VO
간에 서로 변환한다.
IntelliJ http client 를 사용하여 수동 테스트를 처리할 수 있다.
다른 api 테스트 툴을 사용한다면, openapi.json
을 해당 툴에 임포트 하여 쉽게 생성할 수 있을 것이다.
API 추가/수정/삭제시 해당 .http 파일을 업데이트한다. 본 테스트는 개발자에 의한 수동 테스트를 위한 것으로 개발중에 개발자가 필요에 따라 추가하여, API 호출을 테스트할 수 있다.
- Spock 을 사용하여 테스트 코드를 작성한다.
-
Java 17 - Amazon Corretto 17
-
Gradle 7.6.1
-
Springboot 2.7.10
- Spring-web
- Spring-security
- Spring-doc
- Spring-data
-
Lombok
-
MapStruct - bean mapper Reference
-
JWT token authentication
-
Testing
- JUnit5
- Spock
-
MySQL DB 8.0.32