Spring Boot 예제 API. 튜토리얼(Tutorial) CRUD를 제공하며, API Reference 규칙(
.claude/SKILL.md)을 따라 작성되어 있습니다. JaCoCo 및 Sonarqube 는 예시 입니다.
| 구분 | 버전 / 비고 |
|---|---|
| Java | 22 |
| Gradle Wrapper | 8.14.4 |
| Spring Boot | 3.3.2 |
| springdoc-openapi-starter-webmvc-ui | 2.5.0 (OpenAPI 3.1 출력) |
| spring-boot-starter-validation | Boot BOM |
| Lombok | Boot BOM |
| Gson | 2.13.2 |
| JaCoCo | 0.8.14 |
| SonarQube Gradle 플러그인 | 7.2.2.6593 |
- JDK 22 이상
- Gradle Wrapper가 포함되어 있으므로 별도 설치 불필요 (
./gradlew)
./gradlew build # 컴파일 + 테스트 + JaCoCo 리포트
./gradlew bootRun # 8080 포트로 기동
./gradlew test # 단위 테스트만
./gradlew sonar # SonarQube 분석 (build.gradle의 sonar 블록 참고)- 테스트 프레임워크: JUnit 5, Mockito (Standalone
MockMvc) - JaCoCo HTML 리포트:
build/jacocoHtml/index.html - JaCoCo XML 리포트:
build/reports/jacoco/test/jacocoTestReport.xml
Base path: /example/tutorial/api/v1/tutorials
경로 구조는 사내 규칙 /{domain}/{service}/api/{version}/{resource}을 따르며, 리소스는 복수형 명사·kebab-case로 표기합니다.
| 메서드 | 경로 | operationId | 설명 |
|---|---|---|---|
GET |
/ |
getAllTutorials |
목록 조회 (선택 쿼리: ?title=검색어) |
GET |
/{id} |
getTutorialById |
단건 조회 |
POST |
/ |
createTutorial |
신규 생성 |
PUT |
/{id} |
updateTutorial |
수정 |
DELETE |
/{id} |
deleteTutorial |
삭제 |
요청과 응답 스키마는 분리되어 있으며 Bean Validation(@NotBlank 등)이 적용됩니다.
{
"id": 1,
"title": "Spring Boot 입문",
"description": "기초 강의",
"published": false
}모든 응답은 JSend 포맷으로 래핑됩니다.
성공 (2xx)
{ "data": { "...": "..." }, "code": 200, "message": "OK" }목록 — 결과 없음 (200 + 빈 배열)
{ "data": [], "code": 200, "message": "OK" }에러 (4xx · 5xx) — data는 optional
{ "code": 404, "message": "Not Found" }검증 실패처럼 부가 정보가 있으면 data에 담는다.
{ "data": { "title": "must not be blank" }, "code": 400, "message": "Bad Request" }삭제 성공 (204) — 본문 없음.
| Code | 의미 | 비고 |
|---|---|---|
| 200 | OK | 조회 · 수정 성공 |
| 201 | Created | POST 성공 |
| 204 | No Content | DELETE 성공 |
| 400 | Bad Request | Bean Validation 실패 등 |
| 401 | Unauthorized | 인증 실패 |
| 404 | Not Found | 단건 조회 시 미존재 |
| 500 | Internal Server Error | 미처리 예외 |
공통 에러 응답(400 / 401 / 500)은 컨트롤러에 @CommonApiErrorResponses 합성 어노테이션으로 부착되며, 런타임 변환은 @RestControllerAdvice(GlobalExceptionHandler)에서 일괄 처리됩니다.
애플리케이션 실행 후 접근:
| 문서 | URL |
|---|---|
| Swagger UI | http://localhost:8080/swagger-ui.html |
| OpenAPI JSON | http://localhost:8080/v3/api-docs |
- OpenAPI 3.1 출력 (
springdoc.api-docs.version=openapi_3_1) - 인증 스킴(예시):
bearerAuth(JWT,Authorization: Bearer {token}헤더) — 예시 설정이며 실제 인증 로직은 구현되어 있지 않습니다. springdocsecuritySchemes작성 규칙 시연용으로OpenApiConfig에만 등록되어 있습니다. - 응답 스키마는 제네릭 래퍼(
ApiResponse<T>) 대신 구체 문서 타입(TutorialApiResponse,TutorialListApiResponse,ErrorApiResponse)으로 노출되어 클라이언트가 내부 필드까지 읽을 수 있습니다.
src/main/java/org/example/api/
├── ExampleApiApplication.java # 메인 애플리케이션
├── config/
│ └── OpenApiConfig.java # OpenAPI info · servers · securitySchemes
├── controller/
│ └── TutorialController.java # 튜토리얼 REST API
├── docs/ # springdoc 문서 전용 타입
│ ├── CommonApiErrorResponses.java # 400/401/500 합성 어노테이션
│ ├── ErrorApiResponse.java # 에러 응답 스키마 (data optional)
│ ├── TutorialApiResponse.java # 단건 응답 스키마
│ └── TutorialListApiResponse.java # 목록 응답 스키마
├── dto/
│ ├── ApiResponse.java # JSend 런타임 래퍼 (data · code · message)
│ ├── CreateTutorialRequest.java # POST 요청
│ ├── UpdateTutorialRequest.java # PUT 요청
│ └── TutorialResponse.java # 응답 DTO
├── exception/
│ ├── GlobalExceptionHandler.java # @RestControllerAdvice (400 / 404 / 500)
│ └── NotFoundException.java
├── model/
│ └── Tutorial.java # 도메인 모델
└── service/
└── TutorialService.java # 비즈니스 로직 (인메모리 저장)
src/main/resources/
├── application.yml # springdoc OpenAPI 3.1 설정
└── logback-spring.xml
src/test/java/org/example/api/unittest/
├── controller/TutorialControllerTest.java
└── service/TutorialServiceTest.java
이 프로젝트는 사내 API Reference / Response 작성 규칙을 따릅니다.
- 규칙 본문:
.claude/SKILL.md - 원문 규칙:
.claude/original-rules.md - 규칙 → Spring 어노테이션 매핑:
.claude/spring-mapping.md
핵심 사항:
- 경로 구조:
/{domain}/{service}/api/{version}/{resource}· 복수형 명사 · kebab-case · 동사 금지 @Tag/@Operation(operationId, summary, description)/@Parameter(description)/@ApiResponse를 빠짐없이 부착- 요청 · 응답 DTO 분리 (
*Request/*Response) - 응답은 JSend (
data/code/message) - 4xx / 5xx는
@RestControllerAdvice로 일괄 처리,data생략 - 빈 목록은
204가 아닌200 + [] - PR 전 SKILL.md §7 체크리스트로 자가 점검
아래 도구 설정은 예시 / placeholder입니다. 실제 CI 파이프라인과 연결되어 있지 않으며, 사내에서 도입할 때 참고할 수 있는 build.gradle 스니펫 수준으로만 들어가 있습니다.
| 도구 | 설명 |
|---|---|
| SonarQube (예시) | ./gradlew sonar — build.gradle의 sonar { ... } 블록. projectKey·host.url 등은 placeholder. |
| JaCoCo (예시) | 테스트 커버리지 자동 리포트와 라인 · 브랜치 70% 검증 룰(jacocoTestCoverageVerification). 임계치는 예시 값이며 실제 게이트에 연결되어 있지 않습니다. |
테스트 / 예제용 코드입니다.