Spring Boot

[Spring Boot] Swagger-UI 적용

byeongoo 2020. 5. 31. 19:31

오늘은 Swagger를 적용해서 API 문서 자동화를 하는 방법에 대해서 알아보겠습니다. 사이드 프로젝트를 진행하면서 프론트 개발자에게 API정의서를 만들어서 공유를 했었는데, 기존 API가 변경되면 API문서도 같이 변경을 해줘야하고, 실수할 확률도 어느정도 있었습니다. 그 와중에 Swagger-UI라는 것을 찾았고 이를 적용하여 API를 볼 수 있을 뿐만 아니라 API 호출까지 할 수 있었습니다. 아래 사진은 swagger로 API 문서화를한 예시입니다.

1. Swagger-UI란?

  • 일반적인 동작, 패턴 및 일관된 UI로 RESTful API를 공유한다.
  • API가 발전함에 따라 문서를 최신 상태유지한다.
  • API 문서를 생성, 시각화 및 유지 관리가 편리하다.
  • 문서화된 API에 대해 테스트 또한 가능하다.

즉, 자바코드를 작성할때 API에 대한 정보를 코드로 작성하여 문서 자동화를 하는 것입니다. 이렇게 했을 때 기존보다 편한 점은 코드를 짜면서 API 문서를 함께 수정할 수 있기 때문에 나중에 문서를 고치는 귀찮음이 조금 덜해졌습니다. 또한 UI적으로도 보기 편하고, 테스트 또한 가능하다는 장점이 있습니다.

 

아래 사이트에서 스프링부트에 swagger를 적용하는 튜토리얼을 볼 수 있습니다.

https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api

 

Setting Up Swagger 2 with a Spring REST API | Baeldung

Learn how to document a Spring REST API using Swagger 2.

www.baeldung.com

2. 개발환경

  • OS : Window 10
  • IDE : Intellij
  • Framework : Spring Boot2
  • Build Tool : maven
  • Lombok 적용

3. Spring Boot 적용

먼저 pom.xml에 swagger를 사용하기 위해 의존성을 추가해줍니다.

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

이제 Swagger Config 클래스를 작성합니다. 제가 만든 프로젝트의 이름이 Devcrews라 그룹 이름과 제목을 제 프로젝트에 맞게 작성하였습니다. 

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    private ApiInfo apiInfo() {

        return new ApiInfoBuilder()
                .title("Devcrews api info")
                .description("Devcrews API")
                .build();
    }

    @Bean
    public Docket commonApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("DevCrews")
                .apiInfo(this.apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.contest.calendar.controller"))
                .paths(PathSelectors.ant("/api/**"))
                .build();
    }

}
  • Swagger의 구성은 Docket Bean을 중심으로합니다. @EnableSwagger2 애노테이션을 통하여 Swagger2를 활성화 시킵니다.
  • Docket Bean이 정의되면 select () 메소드는 Swagger에 의해 노출 된 엔드 포인트를 제어하는 ​​방법을 제공하는 ApiSelectorBuilder 인스턴스를 리턴합니다.
  • RequestHandlerSelectors 및 PathSelectors를 사용하여 API에 대한 문서를 사용할 수 있도록 지정을 합니다.  RequestHandlerSelectors.any(), pathSelectors.any()를 사용하면 Swagger를 통해 전체 API에 대한 문서를 사용할 수 있습니다. 저는 controller 패키지와 api로 url이 시작하는 부분만 문서화를 하였습니다.

Controller에 적용하기 전 소스입니다. 게시글 번호를 받아서 게시글의 정보를 Json 객체로 반환해주는 부분입니다. SwaggerConfig에서 api로 시작하는 부분을 문서로 만들기로 정의했기 때문에 앞에 "/api/board/{boardNo}"는 문서 자동화 대상이 됩니다.

@Controller
public class BoardController {

    private final BoardServiceImpl boardService;
    private final MemberService memberService;

    @Autowired
    public BoardController(BoardServiceImpl boardService, MemberService memberService){
        this.boardService  = boardService;
        this.memberService = memberService;
    }

    @GetMapping(value="/api/board/{boardNo}")
    public @ResponseBody HashMap<String, Object> getBoardDtl(BoardDto boardDto){

        String resultMsg;
        HashMap<String, Object> resultMap =new HashMap<>();

        try {
            BoardDto resultBoardDto = boardService.getBoardDtl(boardDto);

            resultMap.put("status", HttpStatus.OK);
            resultMap.put("resultCode", "success");
            resultMap.put("boardDto", resultBoardDto);
        } catch(RuntimeException e){
            e.printStackTrace();
            resultMsg="게시글조회에 실패하였습니다.";
            resultMap.put("resultMsg", resultMsg);
            resultMap.put("resultCode", "fail");
        }

        return resultMap;
    }

}

 

이제 Swagger 문서화를 위해 적용한 소스입니다. @ApiOpertaion을 정의해주었고, 파라미터 정보는 @ApiImplicitParams와, @ApiImplicitParam을 통해 정의해주었습니다. @ApiIgnore와 @ModelAttribute 애노테이션을 사용하면 지정한 파라미터만 API문서에 parameter로 지정이 됩니다. 여기서는 boardNo만 파라미터로 등록되는 것 입니다.

@Api(value = "게시글 API")
@Controller
public class BoardController {

    private final BoardServiceImpl boardService;
    private final MemberService memberService;

    @Autowired
    public BoardController(BoardServiceImpl boardService, MemberService memberService){
        this.boardService  = boardService;
        this.memberService = memberService;
    }

    @GetMapping(value="/api/board/{boardNo}")
    @ApiOperation(value = "getBoardDtl", tags = "게시글 상세 페이지 조회")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "boardNo", value = "게시글 번호", dataType = "long", paramType = "query", defaultValue = "16", required = true),
    })
    public @ResponseBody HashMap<String, Object> getBoardDtl(@ApiIgnore @ModelAttribute BoardDto boardDto){

        String resultMsg;
        HashMap<String, Object> resultMap =new HashMap<>();

        try {
            BoardDto resultBoardDto = boardService.getBoardDtl(boardDto);

            resultMap.put("status", HttpStatus.OK);
            resultMap.put("resultCode", "success");
            resultMap.put("boardDto", resultBoardDto);
        } catch(RuntimeException e){
            e.printStackTrace();
            resultMsg="게시글조회에 실패하였습니다.";
            resultMap.put("resultMsg", resultMsg);
            resultMap.put("resultCode", "fail");
        }

        return resultMap;
    }

}

 

이제 localhost:포트번호/swagger-ui.html로 접속을 하면 아래와 같이 작성한 api 정보를 볼 수 있습니다.

 

REFERENCE

https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api

 

Setting Up Swagger 2 with a Spring REST API | Baeldung

Learn how to document a Spring REST API using Swagger 2.

www.baeldung.com

https://linked2ev.github.io/gitlog/2020/01/05/springboot-6-API%EB%AC%B8%EC%84%9C-swagger-%EC%A0%81%EC%9A%A9/

 

6. springboot Swagger-UI 적용

스프링부트에 API문서 자동화 도구인 스웨거를 적용하는 포스팅입니다.

linked2ev.github.io