자바 백엔드 입문 59편. Springdoc OpenAPI로 컨트롤러 코드만으로 Swagger UI API 문서를 자동 생성하는 표준 패턴 풀어쓴 학습 노트.
이 글은 자바 백엔드 입문 시리즈 59편 중 59편이에요. 프론트엔드 개발자에게 "API 문서 주세요" 라는 요청 — Springdoc OpenAPI로 자동 생성하는 표준 패턴.
API 문서 자동화가 필요한 이유
수동 API 문서 (Notion·Confluence·Word)의 함정: - 코드 바꾸면 문서 안 바뀜 → 불일치 - "문서 업데이트해 주세요" 매일 들음 - 프론트가 "문서랑 응답이 다른데요?" 매일 들음
해결 = 코드를 보고 문서가 자동 생성. Springdoc이 표준.
Springdoc OpenAPI — 한 줄 의존성
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'
추가하면 즉시 두 엔드포인트 자동 활성:
/v3/api-docs— OpenAPI 3.0 명세 JSON/swagger-ui.html— Swagger UI (브라우저용)
브라우저에서 http://localhost:8080/swagger-ui.html 접속 — 모든 컨트롤러가 자동 문서화돼 있어요. 추가 설정 0.
자동 인식되는 정보
Springdoc이 컨트롤러 코드에서 자동으로 뽑는 것들:
- URL 경로 (
@GetMapping("/orders/{id}")) - HTTP 메서드 (GET·POST·PUT·DELETE)
- 요청 매개변수 (
@PathVariable·@RequestParam·@RequestBody) - 응답 타입 (반환값 클래스 → 스키마)
- DTO 필드 (Jackson 시리얼라이즈 + Bean Validation 제약)
- 응답 상태 코드 (
@ResponseStatus)
29편 요청 데이터 추출 의 어노테이션들이 그대로 문서로. 회사 코드의 80%가 "한 줄 추가 안 해도 문서 자동".
@Operation·@Schema — 추가 정보 박기
자동 생성 정보가 부족할 때 어노테이션으로 보강.
@RestController
@RequestMapping("/api/orders")
@Tag(name = "주문", description = "주문 관리 API") // 그룹 이름
public class OrderController {
@Operation(
summary = "주문 조회",
description = "주문 ID로 단건 조회. 본인 주문만 조회 가능.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "성공"),
@ApiResponse(responseCode = "404", description = "주문 없음"),
@ApiResponse(responseCode = "403", description = "권한 없음")
})
@GetMapping("/{id}")
public OrderResponse get(
@Parameter(description = "주문 ID", example = "123")
@PathVariable Long id) {
return orderService.findById(id);
}
}
DTO에도.
@Getter @Setter
@Schema(description = "주문 생성 요청")
public class OrderRequest {
@Schema(description = "상품 ID", example = "1", required = true)
@NotNull
private Long productId;
@Schema(description = "수량", example = "2", minimum = "1", maximum = "100")
@Min(1) @Max(100)
private int quantity;
}
Swagger UI에서 각 필드의 설명·예시·제약이 깔끔하게 보여요.
보안 스키마 — JWT 추가
37편 Spring Security 의 JWT를 문서에 박기.
@Configuration
@OpenAPIDefinition(
info = @Info(title = "My Shop API", version = "1.0", description = "쇼핑몰 백엔드 API"),
security = @SecurityRequirement(name = "bearerAuth")
)
@SecurityScheme(
name = "bearerAuth",
type = SecuritySchemeType.HTTP,
scheme = "bearer",
bearerFormat = "JWT"
)
public class OpenApiConfig { }
Swagger UI에 "Authorize" 버튼이 추가 — JWT 토큰 입력하면 모든 요청에 자동 박아 테스트.
그룹 분리 — 외부 API vs 관리자 API
큰 시스템은 "외부용 API" 와 "내부 관리자 API" 를 분리 문서.
@Configuration
public class OpenApiGroupConfig {
@Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("public")
.pathsToMatch("/api/v1/**")
.build();
}
@Bean
public GroupedOpenApi adminApi() {
return GroupedOpenApi.builder()
.group("admin")
.pathsToMatch("/api/admin/**")
.build();
}
}
Swagger UI 상단에 "Select API" 드롭다운 — 그룹별 분리된 문서.
운영 환경 — Swagger UI 보호
/swagger-ui.html 을 운영에 그대로 노출하면 — 외부에 모든 API 구조 공개. 보안 위험.
대응 2가지:
1. 운영에서 비활성화
# application-prod.yml
springdoc:
api-docs:
enabled: false
swagger-ui:
enabled: false
2. Spring Security로 보호
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/swagger-ui/**", "/v3/api-docs/**").hasRole("ADMIN")
.anyRequest().authenticated());
내부 관리자만 접근 가능. 회사 정책에 따라 선택.
응답 예시 — JSON 샘플 박기
@Operation(summary = "주문 생성")
@ApiResponse(responseCode = "200",
content = @Content(
schema = @Schema(implementation = OrderResponse.class),
examples = @ExampleObject(value = """
{
"id": 123,
"amount": 10000,
"status": "PENDING"
}
""")))
@PostMapping
public OrderResponse create(@RequestBody OrderRequest req) { ... }
프론트가 "응답 모양" 명확히 이해 가능. 한국 회사 표준.
코드 = 문서 일치 보장. 프론트가 매번 백엔드에게 "이 API 응답 모양 어떻게 돼요?" 물을 일 없음. 백엔드 변경 시 문서 자동 갱신. 한국 회사 모든 신규 프로젝트가 도입.
한 줄 정리 — Springdoc OpenAPI = 의존성 한 줄로 API 문서 자동 생성. @Operation·@Schema 로 보강. 운영은 Security로 보호. 한국 회사 신규 표준.
시험 직전 한 번 더 — Springdoc 입문자가 매번 헷갈리는 것
- Springdoc OpenAPI = Spring Boot용 OpenAPI 자동 생성
- 의존성 =
springdoc-openapi-starter-webmvc-ui한 줄 - 두 엔드포인트 자동 =
/v3/api-docs(JSON) +/swagger-ui.html(UI) - 추가 설정 0 — 컨트롤러 코드만으로 문서 완성
- 자동 인식 = URL·HTTP 메서드·매개변수·DTO 필드·응답 타입·검증 제약
@Operation= 메서드 단위 설명·요약@Schema= DTO 필드 설명·예시·제약@Tag= 컨트롤러 그룹 이름@Parameter= 매개변수 설명·예시@ApiResponse= 응답 코드별 설명@SecurityScheme= JWT·OAuth2 보안 스키마 정의- Swagger UI에 "Authorize" 버튼 자동
- 그룹 분리 =
GroupedOpenApiBean — public·admin 분리 - 운영 보호 =
enabled: false또는 Security 룰 - 응답 JSON 샘플 =
@ExampleObject(value = "...") - 코드 = 문서 일치 보장
- 한국 회사 신규 프로젝트 표준
- Bean Validation 제약(
@Min·@NotNull)도 자동 문서화 - "이전 세대" = SpringFox (Springdoc로 거의 다 이전)
- Swagger UI 상단에서 "Try it out" 으로 직접 호출 테스트 가능
시리즈 다른 편 (앞뒤 글 모음)
이전 글:
- 54편 — Testcontainers 실제 DB 통합 테스트
- 55편 — @Scheduled로 작업 스케줄링
- 56편 — @Cacheable 캐싱
- 57편 — Spring Boot Actuator
- 58편 — MapStruct DTO 매핑 자동화
다음 글: 시리즈 마지막 편이에요.