# Swagger API 문서화 가이드 **작성일**: 2025-10-16 **버전**: 1.0.0 **프로젝트**: SNP Batch - Spring Batch 기반 데이터 통합 시스템 --- ## 📋 Swagger 설정 완료 사항 ### ✅ 수정 완료 파일 1. **BaseController.java** - 공통 CRUD Controller 추상 클래스 - Java import alias 오류 수정 (`as SwaggerApiResponse` 제거) - `@Operation` 어노테이션 내 `responses` 속성으로 통합 - 전체 경로로 어노테이션 사용: `@io.swagger.v3.oas.annotations.responses.ApiResponse` 2. **ProductWebController.java** - 샘플 제품 API Controller - Java import alias 오류 수정 - 커스텀 엔드포인트 Swagger 어노테이션 수정 3. **SwaggerConfig.java** - Swagger/OpenAPI 3.0 설정 - 서버 포트 동적 설정 (`@Value("${server.port:8081}")`) - 상세한 API 문서 설명 추가 - Markdown 형식 설명 추가 4. **BatchController.java** - 배치 관리 API (이미 올바르게 구현됨) --- ## 🌐 Swagger UI 접속 정보 ### 접속 URL ``` Swagger UI: http://localhost:8081/swagger-ui/index.html API 문서 (JSON): http://localhost:8081/v3/api-docs API 문서 (YAML): http://localhost:8081/v3/api-docs.yaml ``` ### 제공되는 API 그룹 > **참고**: BaseController는 추상 클래스이므로 별도의 API 그룹으로 표시되지 않습니다. > 상속받는 Controller(예: ProductWebController)의 `@Tag`로 모든 CRUD 엔드포인트가 그룹화됩니다. #### 1. **Batch Management API** (`/api/batch`) 배치 작업 실행 및 스케줄 관리 **엔드포인트**: - `POST /api/batch/jobs/{jobName}/execute` - 배치 작업 실행 - `GET /api/batch/jobs` - 배치 작업 목록 조회 - `GET /api/batch/jobs/{jobName}/executions` - 실행 이력 조회 - `POST /api/batch/executions/{executionId}/stop` - 실행 중지 - `GET /api/batch/schedules` - 스케줄 목록 조회 - `POST /api/batch/schedules` - 스케줄 생성 - `PUT /api/batch/schedules/{jobName}` - 스케줄 수정 - `DELETE /api/batch/schedules/{jobName}` - 스케줄 삭제 - `PATCH /api/batch/schedules/{jobName}/toggle` - 스케줄 활성화/비활성화 - `GET /api/batch/dashboard` - 대시보드 데이터 - `GET /api/batch/timeline` - 타임라인 데이터 #### 2. **Product API** (`/api/products`) 샘플 제품 데이터 CRUD (BaseController 상속) **모든 엔드포인트가 "Product API" 그룹으로 통합 표시됩니다.** **공통 CRUD 엔드포인트** (BaseController에서 상속): - `POST /api/products` - 제품 생성 - `GET /api/products/{id}` - 제품 조회 (ID) - `GET /api/products` - 전체 제품 조회 - `GET /api/products/page?offset=0&limit=20` - 페이징 조회 - `PUT /api/products/{id}` - 제품 수정 - `DELETE /api/products/{id}` - 제품 삭제 - `GET /api/products/{id}/exists` - 존재 여부 확인 **커스텀 엔드포인트**: - `GET /api/products/by-product-id/{productId}` - 제품 코드로 조회 - `GET /api/products/stats/active-count` - 활성 제품 개수 --- ## 🛠️ 애플리케이션 실행 및 테스트 ### 1. 애플리케이션 빌드 및 실행 ```bash # Maven 빌드 (IntelliJ IDEA에서) mvn clean package -DskipTests # 애플리케이션 실행 mvn spring-boot:run ``` 또는 IntelliJ IDEA에서: 1. `SnpBatchApplication.java` 파일 열기 2. 메인 메서드 왼쪽의 ▶ 아이콘 클릭 3. "Run 'SnpBatchApplication'" 선택 ### 2. Swagger UI 접속 브라우저에서 다음 URL 접속: ``` http://localhost:8081/swagger-ui/index.html ``` ### 3. API 테스트 예시 #### 예시 1: 배치 작업 목록 조회 ```http GET http://localhost:8081/api/batch/jobs ``` **예상 응답**: ```json [ "sampleProductImportJob", "shipDataImportJob" ] ``` #### 예시 2: 배치 작업 실행 ```http POST http://localhost:8081/api/batch/jobs/sampleProductImportJob/execute ``` **예상 응답**: ```json { "success": true, "message": "Job started successfully", "executionId": 1 } ``` #### 예시 3: 제품 생성 (샘플) ```http POST http://localhost:8081/api/products Content-Type: application/json { "productId": "TEST-001", "productName": "테스트 제품", "category": "Electronics", "price": 99.99, "stockQuantity": 50, "isActive": true, "rating": 4.5 } ``` **예상 응답**: ```json { "success": true, "message": "Product created successfully", "data": { "id": 1, "productId": "TEST-001", "productName": "테스트 제품", "category": "Electronics", "price": 99.99, "stockQuantity": 50, "isActive": true, "rating": 4.5, "createdAt": "2025-10-16T10:30:00", "updatedAt": "2025-10-16T10:30:00" } } ``` #### 예시 4: 페이징 조회 ```http GET http://localhost:8081/api/products/page?offset=0&limit=10 ``` **예상 응답**: ```json { "success": true, "message": "Retrieved 10 items (total: 100)", "data": [ { "id": 1, "productName": "Product 1", ... }, { "id": 2, "productName": "Product 2", ... }, ... ] } ``` --- ## 📚 Swagger 어노테이션 가이드 ### BaseController에서 사용된 패턴 #### ❌ 잘못된 사용법 (Java에서는 불가능) ```java // Kotlin의 import alias는 Java에서 지원되지 않음 import io.swagger.v3.oas.annotations.responses.ApiResponse as SwaggerApiResponse; @ApiResponses(value = { @SwaggerApiResponse(responseCode = "200", description = "성공") }) ``` #### ✅ 올바른 사용법 (수정 완료) ```java // import alias 제거 import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @Operation( summary = "리소스 생성", description = "새로운 리소스를 생성합니다", responses = { @io.swagger.v3.oas.annotations.responses.ApiResponse( responseCode = "200", description = "생성 성공" ), @io.swagger.v3.oas.annotations.responses.ApiResponse( responseCode = "500", description = "서버 오류" ) } ) @PostMapping public ResponseEntity> create( @Parameter(description = "생성할 리소스 데이터", required = true) @RequestBody D dto) { // ... } ``` ### 주요 어노테이션 설명 #### 1. `@Tag` - API 그룹화 ```java @Tag(name = "Product API", description = "제품 관리 API") public class ProductWebController extends BaseController { // ... } ``` #### 2. `@Operation` - 엔드포인트 문서화 ```java @Operation( summary = "짧은 설명 (목록에 표시)", description = "상세 설명 (확장 시 표시)", responses = { /* 응답 정의 */ } ) ``` #### 3. `@Parameter` - 파라미터 설명 ```java @Parameter( description = "파라미터 설명", required = true, example = "예시 값" ) @PathVariable String id ``` #### 4. `@io.swagger.v3.oas.annotations.responses.ApiResponse` - 응답 정의 ```java @io.swagger.v3.oas.annotations.responses.ApiResponse( responseCode = "200", description = "성공 메시지", content = @Content( mediaType = "application/json", schema = @Schema(implementation = ProductDto.class) ) ) ``` --- ## 🎯 신규 Controller 개발 시 Swagger 적용 가이드 ### 1. BaseController를 상속하는 경우 ```java @RestController @RequestMapping("/api/myresource") @RequiredArgsConstructor @Tag(name = "My Resource API", description = "나의 리소스 관리 API") public class MyResourceController extends BaseController { private final MyResourceService myResourceService; @Override protected BaseService getService() { return myResourceService; } @Override protected String getResourceName() { return "MyResource"; } // BaseController가 제공하는 CRUD 엔드포인트 자동 생성: // POST /api/myresource // GET /api/myresource/{id} // GET /api/myresource // GET /api/myresource/page // PUT /api/myresource/{id} // DELETE /api/myresource/{id} // GET /api/myresource/{id}/exists // 커스텀 엔드포인트 추가 시: @Operation( summary = "커스텀 조회", description = "특정 조건으로 리소스를 조회합니다", responses = { @io.swagger.v3.oas.annotations.responses.ApiResponse( responseCode = "200", description = "조회 성공" ) } ) @GetMapping("/custom/{key}") public ResponseEntity> customEndpoint( @Parameter(description = "커스텀 키", required = true) @PathVariable String key) { // 구현... } } ``` ### 2. 독립적인 Controller를 작성하는 경우 ```java @RestController @RequestMapping("/api/custom") @RequiredArgsConstructor @Slf4j @Tag(name = "Custom API", description = "커스텀 API") public class CustomController { @Operation( summary = "커스텀 작업", description = "특정 작업을 수행합니다", responses = { @io.swagger.v3.oas.annotations.responses.ApiResponse( responseCode = "200", description = "작업 성공" ), @io.swagger.v3.oas.annotations.responses.ApiResponse( responseCode = "500", description = "서버 오류" ) } ) @PostMapping("/action") public ResponseEntity> customAction( @Parameter(description = "액션 파라미터", required = true) @RequestBody Map params) { // 구현... } } ``` --- ## 🔍 Swagger UI 화면 구성 ### 메인 화면 ``` ┌─────────────────────────────────────────────────┐ │ SNP Batch REST API │ │ Version: v1.0.0 │ │ Spring Batch 기반 데이터 통합 시스템 REST API │ ├─────────────────────────────────────────────────┤ │ Servers: │ │ ▼ http://localhost:8081 (로컬 개발 서버) │ ├─────────────────────────────────────────────────┤ │ │ │ ▼ Batch Management API │ │ POST /api/batch/jobs/{jobName}/execute │ │ GET /api/batch/jobs │ │ ... │ │ │ │ ▼ Product API (9개 엔드포인트 통합 표시) │ │ POST /api/products │ │ GET /api/products/{id} │ │ GET /api/products │ │ GET /api/products/page │ │ PUT /api/products/{id} │ │ DELETE /api/products/{id} │ │ GET /api/products/{id}/exists │ │ GET /api/products/by-product-id/{...} │ │ GET /api/products/stats/active-count │ │ │ │ (Base API 그룹은 표시되지 않음) │ │ │ └─────────────────────────────────────────────────┘ ``` ### API 실행 화면 예시 각 엔드포인트 클릭 시: - **Parameters**: 파라미터 입력 필드 - **Request body**: JSON 요청 본문 에디터 - **Try it out**: 실제 API 호출 버튼 - **Responses**: 응답 코드 및 예시 - **Curl**: curl 명령어 생성 --- ## ⚠️ 문제 해결 ### 1. Swagger UI 접속 불가 **증상**: `http://localhost:8081/swagger-ui/index.html` 접속 시 404 오류 **해결**: 1. 애플리케이션이 실행 중인지 확인 2. 포트 번호 확인 (`application.yml`의 `server.port`) 3. 다음 URL 시도: - `http://localhost:8081/swagger-ui.html` - `http://localhost:8081/swagger-ui/` ### 2. API 실행 시 401/403 오류 **증상**: "Try it out" 클릭 시 인증 오류 **해결**: - 현재 인증이 설정되지 않음 (기본 허용) - Spring Security 추가 시 Swagger 경로 허용 필요: ```java .authorizeHttpRequests(auth -> auth .requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll() .anyRequest().authenticated() ) ``` ### 3. 특정 엔드포인트가 보이지 않음 **증상**: Controller는 작성했지만 Swagger UI에 표시되지 않음 **해결**: 1. `@RestController` 어노테이션 확인 2. `@RequestMapping` 경로 확인 3. Controller가 `com.snp.batch` 패키지 하위에 있는지 확인 4. 애플리케이션 재시작 --- ## 📊 설정 파일 ### application.yml (Swagger 관련 설정) ```yaml server: port: 8081 # Swagger UI 접속 포트 # Springdoc OpenAPI 설정 (필요 시 추가) springdoc: api-docs: path: /v3/api-docs # OpenAPI JSON 경로 swagger-ui: path: /swagger-ui.html # Swagger UI 경로 enabled: true operations-sorter: alpha # 엔드포인트 정렬 (alpha, method) tags-sorter: alpha # 태그 정렬 ``` --- ## 🎓 추가 학습 자료 ### Swagger 어노테이션 공식 문서 - [OpenAPI 3.0 Annotations](https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Annotations) - [Springdoc OpenAPI](https://springdoc.org/) ### 관련 파일 위치 ``` src/main/java/com/snp/batch/ ├── common/web/controller/BaseController.java # 공통 CRUD Base ├── global/config/SwaggerConfig.java # Swagger 설정 ├── global/controller/BatchController.java # Batch API └── jobs/sample/web/controller/ProductWebController.java # Product API ``` --- ## ✅ 체크리스트 애플리케이션 실행 전 확인: - [ ] Maven 빌드 성공 - [ ] `application.yml` 설정 확인 - [ ] PostgreSQL 데이터베이스 연결 확인 - [ ] 포트 8081 사용 가능 여부 확인 Swagger 테스트 확인: - [ ] Swagger UI 접속 성공 - [ ] Batch Management API 표시 확인 - [ ] Product API 표시 확인 - [ ] "Try it out" 기능 동작 확인 - [ ] API 응답 정상 확인 --- ## 📚 관련 문서 ### 핵심 문서 - **[README.md](README.md)** - 프로젝트 개요 및 빠른 시작 가이드 - **[DEVELOPMENT_GUIDE.md](DEVELOPMENT_GUIDE.md)** - 신규 Job 개발 가이드 및 Base 클래스 사용법 - **[CLAUDE.md](CLAUDE.md)** - 프로젝트 형상관리 문서 (세션 연속성) ### 아키텍처 문서 - **[docs/architecture/ARCHITECTURE.md](docs/architecture/ARCHITECTURE.md)** - 프로젝트 아키텍처 상세 설계 - **[docs/architecture/PROJECT_STRUCTURE.md](docs/architecture/PROJECT_STRUCTURE.md)** - Job 중심 패키지 구조 가이드 ### 구현 가이드 - **[docs/guides/PROXY_SERVICE_GUIDE.md](docs/guides/PROXY_SERVICE_GUIDE.md)** - 외부 API 프록시 패턴 구현 가이드 - **[docs/guides/SHIP_API_EXAMPLE.md](docs/guides/SHIP_API_EXAMPLE.md)** - Maritime API 연동 실전 예제 ### 보안 문서 - **[docs/security/README.md](docs/security/README.md)** - 보안 전략 개요 (계획 단계) --- **최종 업데이트**: 2025-10-16 **작성자**: Claude Code **버전**: 1.1.0