Swagger는 RESTful API의 설계, 빌드, 문서화를 위한 오픈소스 프레임워크로, Spring Boot와 결합하면 개발 중인 API에 대한 실시간 문서를 자동으로 생성할 수 있다. 이를 통해 클라이언트 개발자나 테스트 엔지니어가 API 명세를 쉽게 확인할 수 있다.
Maven 의존성 추가
Spring Boot 2.6 이상에서는 springfox-boot-starter 대신 OpenAPI 3 기반의 springdoc-openapi-starter-webmvc-ui를 권장한다.
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.3.0</version>
</dependency>
기본 설정
추가적인 Java 설정 없이도 기본 기능이 작동하지만, API 그룹이나 메타데이터를 커스터마이징하려면 설정 클래스를 정의할 수 있다.
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class OpenApiConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("샘플 API 문서")
.version("v1.0")
.description("Spring Boot + OpenAPI 연동 예제"));
}
}
컨트롤러에 OpenAPI 주석 적용
각 엔드포인트에 대해 상세 설명을 제공하기 위해 다양한 OpenAPI 어노테이션을 사용할 수 있다.
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Tag(name = "샘플 컨트롤러", description = "테스트용 API 엔드포인트")
public class ExampleController {
@GetMapping("/hello")
@Operation(summary = "간단한 인사말 반환", description = "요청 시 'Hello, World!' 문자열을 응답합니다.")
@ApiResponse(responseCode = "200", description = "성공", content = @Content)
public String sayHello() {
return "Hello, World!";
}
}
Swagger UI 접근
애플리케이션이 실행 중일 때 다음 URL로 Swagger UI에 접근할 수 있다:
http://localhost:8080/swagger-ui.html(springfox 기반)http://localhost:8080/swagger-ui/index.html(springdoc 기반)
springdoc을 사용하는 경우 일반적으로 /swagger-ui/index.html 경로가 기본이다.
전역 예외 처리 통합
예외 발생 시 API 문서에 오류 응답 스키마를 표시하려면 전역 예외 핸들러를 정의하고, 해당 예외 유형을 OpenAPI 문서에 반영해야 한다.
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class ApiExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<String> handleIllegalArgument(IllegalArgumentException ex) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ex.getMessage());
}
}
Spring Security와의 통합
Spring Security를 사용 중이라면 Swagger 관련 리소스에 대한 접근을 허용해야 UI가 정상적으로 로드된다.
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(authz -> authz
.requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
.anyRequest().authenticated()
);
return http.build();
}
}