본문 바로가기
SpringBoot

Swagger를 이용한 Springboot Restful API 문서 자동화 하기

by 정ㅇr 2022. 4. 21.
728x90

회사에 있는 코드가 문서화 되어 있지 않은 관계로

인수인계가 불편하고, 코드를 파악하기에도 힘든 이유로 Swagger 적용을 하자는 이야기가 나왔다.

 

그래서 처음 사용해보게 된 Swagger!

블로그에 정리해두면 나한테도, 다른 사람에게도 도움이 될 것 같아서

간단하게 정리하려고 오랜만에 블로그에 방문했다.

 

그러면 서론이 길어지니, 본론으로 들어가겠음.

 

Swagger란?

스웨거(Swagger)는 개발자가 REST 웹 서비스를 설계, 빌드, 문서화, 소비하는 일을 도와주는 대형 도구 생태계의 지원을 받는 오픈 소스 소프트웨어 프레임워크이다. 대부분의 사용자들은 스웨거 UI 도구를 통해 스웨거를 식별하며 스웨거 툴셋에는 자동화된 문서화, 코드 생성, 테스트 케이스 생성 지원이 포함된다.

 

출처 - 위키백과

 

먼저 내가 적용한 프로젝트의 구성은

- MySQL version 8.0.5

- SpringBoot

- Maven

- Java 1.8

정도로 되어 있다.

 

1. 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>

- springfox-swagger2는 적용된 프로젝트의 응답, 요청, 예시 등의 정보를 JSON 형식으로 만들어준다.

- springfox-swagger-ui는 swagger2로 구성된 JSON 파일을 웹페이지 형식으로 보여준다.

 

이번에 적용한 버전은 Swagger2 2.9.2인데, 이전 버전에서는 annotation, models도 있었다고 한다.

지금은 사용하지 않는 이유는 다른 블로그 글을 참고해서 알 수 있었다.

 

주의 깊게 봐야 할 점은 gradle, maven 모두 해당 버전의 swagger-annotations, swagger-models를 제거하고 1.5.21 버전의 annotaions, models를 추가했다는 점인데요.

 

이유는 2.9.2 버전에서 Long 타입의 필수 파라미터에 example이 없는 경우 "" 공백이 Long 타입 파라미터에 들어가기 때문에 아래와 같이 NumberFormatException이 발생하기 때문입니다.

출처 : https://wildeveloperetrain.tistory.com/3

 

 

2. SwaggerConfig 파일 만들기

나같은 경우에는 com.xxx.yyy.config 아래에 SwaggerConfig.java 파일을 생성했다.

사람마다 폴더 구조가 다를 수 있으니 그 부분은 넘어가도록 하겠다.

 

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;


@Configuration
@EnableSwagger2
@EnableAutoConfiguration
public class SwaggerConfig {
    private static final String API_NAME = "문서 이름";
    private static final String API_VERSION = "버전 써주기";
    private static final String API_DESCRIPTION = "문서에 대한 설명쓰기";

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title(API_NAME)
                .description(API_DESCRIPTION)
                .build();
    }

    @Bean
    public Docket commonApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName(API_VERSION)
                .apiInfo(this.apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("API가 들어있는 폴더 경로 써주기, 예) com.xxx.yyy.controller"))
                .paths(PathSelectors.any())
                .build();
    }
}

- Swagger2는 @EnableSwagger2 어노테이션으로 설정이 가능하다.

- Docket은 문서화를 해주는 객체라고 보면 된다. select() 메소드는 ApiSelectorBuilder를 생성한다.

- apis()는 api 정보가 작성되어 있는 패키지를 지정한다. 내 경우는 controller 패키지 경로가 된다.

- paths()는 path 조건에 해당하는 API를 찾아서 문서화 해주는 메소드다.

- 여기서 apiInfo는 이름 그대로 API 문서의 내용을 담고 있다.

 

 

 

3. 문서 작성을 위해 기존 코드에 어노테이션 추가 및 일부 수정

먼저 내가 적용한 프로젝트의 Controller 기존 코드다.

import com.zapple.server_memory_check_web.service.MainService;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;

@RestController
@RequestMapping("/api")
public class MainController {
    @Autowired
    MainService mainService;

    @GetMapping("/data")
    public String getServerData() throws IOException, ParseException {
        return mainService.getServerData();
    }

    ...
}

 

아래는 필요한 어노테이션과 코드를 추가한 내용이다.

import com.zapple.server_memory_check_web.service.MainService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;

@RestController
@Api(value = "MainController")
@RequestMapping("/api")
public class MainController {
    @Autowired
    MainService mainService;

    @ApiOperation(value = "test", notes = "테스트")
    @ApiResponses({
            @ApiResponse(code = 200, message = "OK"),
            @ApiResponse(code = 500, message = "server error"),
            @ApiResponse(code = 404, message = "not found")
    })

    @GetMapping("/data")
    public String getServerData() throws IOException, ParseException {
        return mainService.getServerData();
    }

    ...
}

- @Api : Swagger의 리소스를 명시한다. 여기서는 프로젝트의 Controller의 이름이 되겠다.

- @ApiOperation : API에 대한 간단한 설명

- @ApiResponse : API 응답 코드에 따른 메세지 설정

 

4. 해당 주소/swagger-ui.html 주소로 이동

나는 로컬 환경에서 실행했기 때문에 주소가 http://localhost:8080/swagger-ui.html 다음과 같다.

 

아마도 스프링부트를 실행시키다가 오류가 났을 수도 있다.

 

"Failed to start bean 'documentationPluginsBootstrapper' .. " 라고 오류가 났다면,

SpringBoot 버전을 2.4.2로 낮추면 해결된다.

SpringBoot와 Swagger 사이에 호환 문제가 있는 듯하다.

 

다음과 같이 API에 정보들이 깔끔한 UI에 나타나게 된다.

 

기본적인 설정만 해봤기에 아마도 Swagger 자체에 다양한 기능들이 있을 것이다.

일단 Swagger를 SpringBoot에 적용하는 과정만 해봤기 때문에 

오늘은 이쯤에서 소개를 마치겠다. 

반응형

댓글