[Spring Boot] Springdoc 라이브러리를 통한 Swagger 적용
목차
기본 환경
- IntelliJ Ultimate 2022.3
- Spring Boot 2.7.7
- Kotlin 1.7.21(JDK 11)
- Springdoc Openapi UI 1.6.11
Springdoc은 무엇인가?
이전에 Spring Boot 프로젝트에 Swagger UI를 적용하는 포스트를 작성한 적이 있다. 해당 포스트를 작성할 당시에는 Swagger UI를 제공하는 라이브러리가 Springfox만 존재하는 줄 알았는데, Springdoc이라는 라이브러리에서도 Swagger UI를 제공한다는 사실을 알게되어 이 포스트를 작성하게 되었다.
최근에는 Springdoc을 사용하는 것이 더 선호된다고 한다. Springfox의 경우에는 2020년 7월 이후로 업데이트가 중단된 반면, Springdoc은 최근까지도 지속적으로 업데이트중이기 때문이다. 따라서 이 포스트에서는 이전에 Springfox를 사용하여 작성한 Swagger 예제를 Springdoc으로 마이그레이션하는 내용을 주로 다룰 것이다.
Springfox와 Springdoc는 무엇이 다른가?
두 가지의 Swagger UI를 모두 사용하면서 가장 크게 와닿은 것은 Springdoc의 경우엔 JSON 형태의 데이터에서 key와 value를 구분하기 쉽게 색을 나눠놨다는 점이다.
그 외에도 Springdoc은 Webflux를 통한 비동기 방식의 개발을 지원한다.
의존성 목록에 Springdoc 라이브러리 추가(2023-03-07 내용 추가)
Spring Boot 3 이전 버전은 Springdoc을 사용하기 위해 빌드 환경에 따라 gradle.build / gradle.build.kts / pom.xml에 다음 코드를 추가한다.
Gradle
implementation("org.springdoc:springdoc-openapi-ui:1.6.11")
Maven
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.11</version>
</dependency>
Spring Boot 3버전부터는 위의 의존성 라이브러리를 추가하면 스웨거 UI 접속 시 404 에러가 발생하기 때문에 다음 코드를 추가해야 한다.(2023-03-07 추가내용)
참고 링크
[Swagger] Spring Boot 3.0.X 버전에서 Swagger UI 접속 시 404 에러가 발생할 때
Gradle
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2")
Maven
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.0.2</version>
</dependency>
Swagger 사용을 위한 기본 설정
Springdoc은 Swagger UI 설정을 하는 방법이 Springfox와 다소 차이가 있다. Springfox는 별도의 config 클래스에서 대부분의 설정을 하였지만 Springdoc는 config 클래스에서 API 문서페이지의 기본 설명만 작성하고 나머지 설정은 모두 application.properties 혹은 application.yml에서 설정한다. 또한 config 클래스에 @EnableWebMvc
어노테이션을 붙이지도 않는다.
SwaggerConfig
// Kotlin
import io.swagger.v3.oas.models.Components
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
class SwaggerConfig {
@Bean
fun openAPI(): OpenAPI = OpenAPI()
.components(Components())
.info(apiInfo())
private fun apiInfo() = Info()
.title("Springdoc 테스트")
.description("Springdoc을 사용한 Swagger UI 테스트")
.version("1.0.0")
}
// Java
import io.swagger.v3.oas.models.Components;
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 SwaggerConfig {
@Bean
public OpenAPI openAPI() {
return new OpenAPI()
.components(new Components())
.info(apiInfo());
}
private Info apiInfo() {
return new Info()
.title("Springdoc 테스트")
.description("Springdoc을 사용한 Swagger UI 테스트")
.version("1.0.0");
}
}
application.yml
springdoc:
packages-to-scan: com.colabear754.springdoc_example.controllers
default-consumes-media-type: application/json;charset=UTF-8
default-produces-media-type: application/json;charset=UTF-8
swagger-ui:
path: /
disable-swagger-default-url: true
display-request-duration: true
operations-sorter: alpha
각 속성에 대한 정보는 아래 링크에서 확인할 수 있다.
https://springdoc.org/#properties
properties와 yml의 차이는 다음 포스트를 참고바란다.
Swagger 문서에 API 등록
Springdoc도 Springfox와 마찬가지로 application 속성의 springdoc.packages-to-scan
에 설정해놓은 패키지 내부의 클래스는 모두 자동으로 Swagger 문서에 등록된다. 만약 등록하고 싶지 않은 컨트롤러가 있다면 @Hidden
어노테이션을 이용하여 숨길 수 있다.
Springdoc에서는 Swagger UI를 위한 어노테이션이 변경되었다. 어노테이션 외에는 변경할 점이 없기 때문에 컨트롤러에서 어노테이션만 변경해주면 된다.
// Kotlin
import io.swagger.v3.oas.annotations.Hidden
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.Parameter
import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
@Tag(name = "예제 API", description = "Swagger 테스트용 API")
@RestController
@RequestMapping("/")
class ExampleController {
@Operation(summary = "문자열 반복", description = "파라미터로 받은 문자열을 2번 반복합니다.")
@Parameter(name = "str", description = "2번 반복할 문자열")
@GetMapping("/returnStr")
fun returnStr(@RequestParam str: String) = "$str\n$str"
@GetMapping("/example")
fun example() = "예시 API"
@Hidden
@GetMapping("/ignore")
fun ignore() = "무시되는 API"
}
// Java
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "예제 API", description = "Swagger 테스트용 API")
@RestController
@RequestMapping("/")
public class ExampleController {
@Operation(summary = "문자열 반복", description = "파라미터로 받은 문자열을 2번 반복합니다.")
@Parameter(name = "str", description = "2번 반복할 문자열")
@GetMapping("/returnStr")
public String returnStr(@RequestParam String str) {
return str + "\n" + str;
}
@GetMapping("/example")
public String example() {
return "예시 API";
}
@Hidden
@GetMapping("/ignore")
public String ignore() {
return "무시되는 API";
}
}
Springdoc 공식 가이드에서 설명하는 어노테이션의 변화는 다음과 같다.
@Api
→@Tag
@ApiIgnore
→@Parameter(hidden = true)
or@Operation(hidden = true)
or@Hidden
@ApiImplicitParam
→@Parameter
@ApiImplicitParams
→@Parameters
@ApiModel
→@Schema
@ApiModelProperty(hidden = true)
→@Schema(accessMode = READ_ONLY)
@ApiModelProperty
→@Schema
@ApiOperation(value = "foo", notes = "bar")
→@Operation(summary = "foo", description = "bar")
@ApiParam
→@Parameter
@ApiResponse(code = 404, message = "foo")
→@ApiResponse(responseCode = "404", description = "foo")
Spring Boot 프로젝트를 실행한 후 application 속성에서 설정한 포트와 경로로 이동하면 API가 등록되어 있는 Swagger UI 문서를 확인할 수 있다.
Swagger에 등록된 API 테스트
Springfox의 Swagger와 마찬가지로 Try it out 버튼을 클릭하면 API를 테스트할 수 있다.
API가 정상적으로 동작하는 것을 확인할 수 있다.