[SpringBoot] 스프링부트 Swagger 2 적용법 및 예외 처리
오늘은 스프링부트에 Swagger2를 적용하는 방법에 대해 알아보려한다.
Swagger란?
Swagger는 API가 어떤 Spec을 가진 데이터를 주고 받는지 시각적으로 확인할 수 있도록 도와주는 API 문서 자동화 프레임워크이다.
위와 같이 API URI를 확인할 수 있을 뿐더러 직접 파라미터를 입력해 테스트도 진행할 수 있는 엄청난 프레임워크다.
적용
이제 이 Swagger를 직접 사용할 수 있도록 적용해보자.
우선 의존성을 추가해주어야한다.
build.gradle
// springfox-swagger-ui
implementation group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2'
implementation group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'
pom.xml
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
의존성은 build.gradle과 pom.xml을 나눠 제공했지만 설명은 gradle 프로젝트로 진행되니 참고하자.
의존성을 추가해줬으니 이번엔 SwaggerConfig를 추가해주어야 한다.
SwaggerConfig
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
//http://localhost:8080/swagger-ui.html#
@Configuration
@EnableSwagger2
public class SwaggerConfig implements WebMvcConfigurer {
private static final String API_NAME = "TestProject API";
private static final String API_VERSION = "0.0.1";
private static final String API_DESCRIPTION = "TestProject API 명세서";
@Override public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/"); }
@Bean
public Docket swagger() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo()) //apiInfo 삽입
.select() //ApiSelectorBuilder를 생성
.apis(RequestHandlerSelectors.basePackage("dnd.project.dnd6th7worryrecordservice")) //API 범위 지정 (해당 패키지 내부에 있는 모든 Request 출력)
.paths(PathSelectors.any()) //스웨거 html 페이지에 모든 URL 제공
//.paths(PathSelectors.ant("/test/**")) 스웨거 html 페이지에 특정 api만 보여주고 싶다면 해당 부분 설정
.build(); }
public ApiInfo apiInfo() { //ApiInfo 설정
return new ApiInfoBuilder()
.title(API_NAME)
.version(API_VERSION)
.description(API_DESCRIPTION)
.build();
}
}
우선 application.yml에 설정값을 하나 추가하자.
Spring boot 2.6버전 이후에 spring.mvc.pathmatch.matching-strategy 값이 ant_apth_matcher에서 path_pattern_parser로 변경되면서 몇몇 라이브러리(swagger포함)에 오류가 발생하여 ApplicationContectException이 발생한다.
org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper';
이러한 예외가 나타는데 application.yml에 아래 내용을 추가해주면 해결된다.
spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
이제 본격적으로 설명에 들어가겠다.
addResourceHandlers는 WebMvcConfigurer 을 상속받아 @Override 해야한다.
이 부분은 Swagger를 사용하는데 꼭 필요한 부분이다.
Swagger를 사용하기 위해 세팅을 하고 swagger-ui.html에 진입해도 404 Not found가 발생하는 경우가 있다.
별거 아닌 이슈지만 해결법을 모른다면 한참을 해매야 한다.
Swagger 2.9.* 이상에서 발생하는 오류인데 이럴 경우에 Config파일에 addResourceHandlers를 오버라이딩 해서 직접 swagger-ui.html 파일의 위치를 작성해주어야 하는 것이다.
보통 위에 작성해둔 경로에 있으니 필요한 사람은 그대로 긁어서 사용해도 문제가 없을 것이다.
Docket 은 Swagger 설정을 위한 Bean이다.
작성한 apiInfo를 넣어주고 select()로 ApiselectorBuilder를 생성하여 Url과 Api의 범위를 지정한 후 build해 주었다.
위처럼 작성하면 스웨거 기본세팅이 끝난다.
Controller 설정
이제 Api에 대한 설명을 편하게 볼 수 있도록 Controller에 직접 설명을 커스텀하여 적어줄 것이다.
@RequiredArgsConstructor
@RequestMapping("/auth")
@RestController
public class KakaoController {
private final JwtUtil jwtUtil;
private final KakaoService kakaoService;
private final UserService userService;
@ApiOperation(value = "토큰 발급", notes = "JWT AccessToken, RefreshToken 을 발급한다")
@ApiResponses({
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 404, message = "No param")
//Other Http Status code..
})
@ApiImplicitParam(
name = "token"
, value = "카카오 엑세스 토큰"
, defaultValue = "None")
@PostMapping(value = "/login")
public ResponseEntity<UserResponseDto> giveToken(@RequestParam("token") String accessToken, HttpServletResponse res) {
@ApiOperation: 해당 method의 설명을 추가할 수 있다.
value : 이름
notes : 설명
@ApiResponse: 해당 method의 상태코드에 따른 응답 메시지를 지정할 수 있다.
code : 상태코드
message : 상태코드에 따른 응답 메시지
@ApiImplicitParam: 파라미터에 대한 정보 추가, ApiResponses 처럼 구조를 짜면 복수 작성도 가능하다.
name : 파라미터 이름
value : 보여줄 파라미터 이름
위의 설정들을 마치면 최종적으로 이러한 화면이 도출된다.
그리고 아래와 같이 직접 테스트 해볼 수도 있다.
기본적인 내용이니 여기서 마치도록 하겠다.
읽어주셔서 감사합니다!