본문 바로가기
  • 개발하는 곰돌이
Development/Spring & Spring Boot

[Spring Boot] Springdoc 라이브러리를 통한 Swagger 적용

by 개발하는 곰돌이 2023. 1. 15.

목차

    기본 환경

    • 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으로 마이그레이션하는 내용을 주로 다룰 것이다.

    마지막 릴리즈가 2020년 7월 14일인 Springfox.
    꾸준히 업데이트 중인 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의 차이는 다음 포스트를 참고바란다.

    [Spring Boot] application.properties와 application.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가 정상적으로 동작하는 것을 확인할 수 있다.

    참조링크

    Springdoc 공식 가이드

    본문 예제 Github

    댓글