ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring Boot - Swagger 라이브러리를 활용하여 API 문서 자동화하기
    Framework & Library/Spring Boot 2023. 1. 19. 17:32

    Swagger 라이브러리를 활용하여 API 문서 자동화하기

    Swagger란?

    API 문서는 API 사용 방법을 사용자에게 알려주는 문서이다. API를 잘 사용하기 위해서는 API 문서를 잘 활용해야 한다. API 문서에는 아래와 같은 정보들이 포함된다.

     

    1. 요청 URL

    2. 해당 API에 대한 설명

    3. 헤더 정보

    4. 요청 파라미터

    5. 응답 데이터

    6. 요청 파라미터와 응답 데이터에 대한 설명

    7. API 호출에 대한 응답 샘플 등

     

    위와 같은 정보들을 제공해 주는 문서는 잘 설명되어 있어야 사용자들이 문의 없이 API를 잘 사용할 수 있을 것이다. 또한 MAS에서는 API로 주로 통신하기 때문에, 문서화가 잘 되어 있어야 한다.

     

    API 문서는 중요하지만, API 스펙을 하나의 문서로 관리하는 것은 귀찮은 일이다. 개인 프로젝트의 경우 문서화에 시간을 투자하는 것은 여간 번거로운 일이 아니다.  이러한 귀찮은 일을 자동화시켜 주는 라이브러리인 Swagger가 존재한다.

     

    Spring Boot에서 Swagger를 사용하면, 컨트롤러에 명시된 애너테이션을 해석하여 API 문서를 자동으로 만들어준다. 또한 Swagger에서 만들어주는 문서 페이지에서 테스트까지 할 수 있기 때문에, 가볍게 사용하기에 적합하다.

     

    의존성 추가
    implementation 'io.springfox:springfox-swagger2:2.9.2'
    implementation 'io.springfox:springfox-swagger-ui:2.9.2'

    Swagger 라이브러리를 사용하기 위해서는 build.gradle 파일에 springfox-swagger2를 의존성에 추가해야 한다. 추가적으로, 문서를 예쁘게 보여주고 테스트 기능을 위해 springfox-swagger-ui 의존성도 추가해 주겠다.

     

    Swagger 설정
    @Configuration
    @EnableSwagger2
    public class SwaggerConfig {
        private String version;
        private String title;
    
        @Bean
        public Docket apiV1() {
            version = "V1";
            title = "swagger-basic API" + version;
    
            return new Docket(DocumentationType.SWAGGER_2)
                    .useDefaultResponseMessages(false)
                    .groupName(version)
                    .select()
                    .apis(RequestHandlerSelectors.basePackage(""))
                    .paths(PathSelectors.ant("/v1/api/**"))
                    .build()
                    .apiInfo(apiInfo(version, title));
        }
    
        @Bean
        public Docket apiV2() {
            version = "V2";
            title = "swagger-basic API" + version;
    
            return new Docket(DocumentationType.SWAGGER_2)
                    .useDefaultResponseMessages(false)
                    .groupName(version)
                    .select()
                    .apis(RequestHandlerSelectors.basePackage(""))
                    .paths(PathSelectors.ant("/v2/api/**"))
                    .build()
                    .apiInfo(apiInfo(version, title));
        }
    
        private ApiInfo apiInfo(String version, String title) {
            return new ApiInfo(
                    title,
                    "Swagger로 생성한 API Docs",
                    version,
                    "www.example.com",
                    new Contact("Contact Me", "www.example.com", "foo@example.com"),
                    "Licenses",
                    "www.example.com",
                    new ArrayList<>()
            );
        }

    Swagger 설정을 위해 SwaggerConfig 클래스를 생성한다. RESTful API는 버전관리가 되어야 하기 때문에, Docket Bean 단위로 버전관리를 작성하였다.

     

    1. @EnableSwagger2

     - Swagger2 버전을 활성화하겠다는 애너테이션이다.

     

    2. Docket

     - Swagger 설정의 핵심이 되는 Bean이다.

       

        2-1. useDefaultResponseMessages()

         - false로 설정하면, Swagger에서 제공해 주는 응답코드(200, 401, 403, 404)에 대한 기본 메시지를 제거한다.

         - 불필요한 응답코드와 메시지를 제거하기 위함이며, 보통 컨트롤러에서 명시해 준다.

     

        2-2. groupName()

         - Docket Bean이 한 개일 경우, 기본 값은 default이므로 생략이 가능하다.

         - Docket Bean이 여러 개일 경우, groupName이 충돌하지 않아야 하므로 서로 다르게 명시해 주어야 한다.

     

        2-3. select()

         - ApiSelectorBuilder를 생성한다.

     

        2-4. apis()

         - api 스펙이 작성되어 있는 패키지를 지정한다.

         - 컨트롤러가 존재하는 패키지를 basePackage로 지정하여, @RequestMapping 애너테이션이 선언된 API를 문서화한다.

     

        2-5. paths()

         - apis()로 선택된 API 중 특정 path 조건에 맞는 API들을 필터링하여 다시 문서화한다.

     

        2-6. apiInfo()

         - 제목, 설명 등 문서에 대한 정보들을 보여준다.

     

    public ApiInfo(title, description, version, termsOfServiceUrl, contact, license, licenseUrl, vendorExtensions)

     - 파라미터에 대한 정보는 위와 같다.

     

     

    Swagger 설정만으로는 실행할 수 없지만, 각 설정의 정보들이 어디에 위치해 있는지 미리 확인하기 위해 최종 Swagger UI를 확인해 보겠다.

     

    1. /swagger-ui.html URL로 접근하면 Swagger가 만들어주는 API 문서 페이지에 접근이 가능하다.

     

    2. Docket을 2개 생성했기 때문에 2개의 스펙이 존재하며, 해당 이름은 groupName 값이다.

     

    3. ApiInfo의 title 정보이다,

     

    4. ApiInfo의 version 정보이다.

     

    5. ApiInfo의 description 정보이다.

     

    6. ApiInfo의 나머지 정보들이다.

     

    Controller 생성
    @RestController
    @Api(value = "BoardController V1")
    @RequestMapping("/v1/api")
    public class BoardControllerV1 {
    
        @ApiOperation(value = "exam", notes = "예제입니다.")
        @ApiResponses({
                @ApiResponse(code = 200, message = "OK"),
                @ApiResponse(code = 500, message = "Internal Server Error"),
                @ApiResponse(code = 404, message = "Not Found")
        })
        @GetMapping(value = "/board")
        public Map<String, String> selectOneBoard(@ApiParam(value = "게시판 번호", required = true, example = "1") @RequestParam String no) {
            Map<String, String> result = new HashMap<>();
            result.put("author", "홍길동");
            result.put("content", "V1 API 내용");
            return result;
        }
    }

    API 요청을 위한 BoardControllerV1 클래스를 생성한다.

     

    1. @Api

     - 해당 클래스가 Swagger 리소스라는 것을 명시하는 애너테이션이다.

     - value : 태그를 작성한다.

     - tags : 여러 개의 태그를 정의할 수 있다.

     

    2. @ApiOperation

     - 하나의 API에 대한 정보를 명시하는 애너테이션이다.

     - value : API에 대한 간략한 설명을 작성한다.

     - notes : API에 대한 구체적인 설명을 작성한다.

     

    3. @ApiResponse

     - API의 가능한 응답을 명시하는 애너테이션이다.

     - code : 응답코드를 작성한다.

     - message : 응답에 대한 설명을 작성한다.

     - responseHeaders : 헤더를 추가할 수 있다.

     

    4. @ApiParam

     - API의 파라미터에 대한 정보를 명시하는 애너테이션이다.

     - value : 파라미터 정보를 작성한다.

     - required : 필수 파라미터일 경우는 true, 아닐 경우는 false를 작성한다.

     - example : 해당 파라미터의 예시를 작성한다.

     

     

    위에서 작성한 API는 /swagger-ui 경로에서 확인이 가능하다.

     

     

    위의 초록색으로 표시된 Try it out 버튼을 클릭하면 실제 API를 바로 테스트해 볼 수 있다.

     

    response를 글로벌 메시지로 설정

    각  API마다 response를 작성하는 것은 번거로운 일이다. 그래서 SwaggerConfig 파일에서 globalResponseMessage()로 모든 API에 공통된 응답 메시지를 작성해 줄 수 있다.

     

    @Configuration
    @EnableSwagger2
    public class SwaggerConfig {
        private String version;
        private String title;
    
        @Bean
        public Docket apiV1() {
            version = "V1";
            title = "swagger-basic API " + version;
    
            return new Docket(DocumentationType.SWAGGER_2)
                    .globalResponseMessage(RequestMethod.GET, getResponseMessages())
                    .groupName(version)
                    .select()
                    .apis(RequestHandlerSelectors.basePackage(""))
                    .paths(PathSelectors.ant("/v1/api/**"))
                    .build()
                    .apiInfo(apiInfo(version, title));
        }
        
        private List<ResponseMessage> getResponseMessages() {
            List<ResponseMessage> responseMessages = new ArrayList<>();
            
            responseMessages.add(new ResponseMessageBuilder()
                    .code(200)
                    .message("OK")
                    .build());
            
            responseMessages.add(new ResponseMessageBuilder()
                    .code(404)
                    .message("Not Found")
                    .build());
            
            responseMessages.add(new ResponseMessageBuilder()
                    .code(500)
                    .message("Internal Server Error")
                    .build());
    
            return responseMessages;
        }
    }

    SwaggerConfig 클래스에 ResponseMessage 목록을 반환하는 getResponseMessages() 메서드를 작성한 후, Docket의 globalResponseMessage() 메서드를 통해 공통 응답 메시지를 지정한다.

     

     

    Swagger UI를 확인해 보면 프로그래머가 정의한 공통 응답 메시지를 확인할 수 있다.


    출처

    https://victorydntmd.tistory.com/341

     

    728x90

    댓글

Designed by Tistory.