Web Dev

Springfox-Swagger2 사용해보기

DuL2 2022. 7. 29. 14:43

Swagger

Swagger란 REST APU의 문서화를 위해 사용하는 것.
단순히 postman처럼 테스팅하는 용도로 사용되는 줄 알았으나 라이브러리로서 개발자가 REST API 문서 작성을 쉽고 간단하게 자동화하도록 도와준다. 간단한 설정만으로도 API 목록을 웹에서 확인 가능하고 테스트까지 가능하게 해주는 라이브러리다.

작은 과제 프로젝트를 위해 직접 작성했었는데 이번에는 Swagger를 공부하고 도입하여 과제 프로젝트 REST API 문서를 작성해보려고 한다.

REST API 문서화는 왜 필요한가?

프로젝트의 개발과 유지보수 과정에서 API의 규격을 정의한 문서는 반드시 필요하다.

만약 API 문서가 없다면 API를 확인할 때 시간 낭비가 생기고 소통의 문제가 생길 것이며 테스트를 진행할 때도 코드를 분석하는 일이 생길 것이다.

이런 문서화 작업도 상당한 시간을 소요하게 만드는 요인인데 역시 개발자들은 무엇이든 만들어 내는 것 같다.

Swagger를 사용해보자.

gradle implements

아래 두개를 추가하면 된다.

    implementation "io.springfox:springfox-swagger2:2.9.2"
    implementation "io.springfox:springfox-swagger-ui:2.9.2"

Swagger 사용 설정

@Configuration
@EnableSwagger2
public class SwaggerConfig extends WebMvcConfigurationSupport {
    //스웨거 REST API DOC 페이지에 안내될 설명 설정.
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("이노베이션 Spring 숙련 주차 과제 프로젝트")
                .description("과제 API 명세")
                .build();
    }

    @Bean
    public Docket commonApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("swg-post")//빈설정에 대한 그루핑을 한 그룹에 대한 구분자 값 설정.
                .apiInfo(this.apiInfo())//스웨거 설명
                .select()//apis, paths를 사용하주기 위한 builder
                .apis(RequestHandlerSelectors.basePackage("com.ldu.spring_blogcrud.controller"))//탐색할 클래스 필터링
                .paths(PathSelectors.any())//스웨거에서 보여줄 api 필터링
                .build();
    }

    @Override //swagger-ui.html 찾을 수 없다는 오류 발생시 추가.
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}

이후 http://localhost:8080/swagger-ui.html로 접속시 다음과 같이 모든 api가 자동으로 작성되어 나옴.(대박)

이제 할 일은 각 api 별 설명과 이름을 anotation을 달아주면 된다.

추가 설정

  • @Api: 해당 API 설명
  • @ApiOperation: 해당 메소드의 API 설명
  • @ApiImplicitParams: Request를 통해 들어오는 param 값 설명
  • @ApiIgnore: 컨트롤러나, 메소드, 파라미터 등의 설명 생략(문서에 보이지 않음.)
  • @ApiModelProperty: 요청, 응답에 대한 각 key의 설명(의미) - 객체의 필드에 어노테이션
  • @ApiResponses: 요청된 메서드가 응답해야하는 코드와 그 설명을 명시

Swagger를 통한 테스트

http://localhost:8080/swagger-ui.html를 통해 테스트 또한 즉석에서 해볼 수 있다. 테스트를 원하는 api를 선택한 후 try it out 버튼을 눌러 파라미터가 필요하다면 설정하고 Execute 버튼을 클릭하면 api를 테스트 해볼 수 있다.

@ApiOperation 사용 예시

아래처럼 @ApiOperation를 사용하여 메소드 api 설명을 정의하게 되면 swagger 페이지에서도 변하게 된다.

    @GetMapping(path = "/api/posts")
    @ApiOperation(value = "전체 게시글 목록 조회", notes = "전체 게시글 목록을 조회한다.")
    public List<PostResponseDto> getPosts() {
        return postService.getPostsList();
    }

value의 default 값은 메소드 이름으로 잡혀있는 듯하다

@ApiModelProperty 사용 예시

본인은 Response 객체를 아직 만들지 않아 ResponseDto 객체 필드에 각 값을 설명해주는 코드를 넣었다

public class PostResponseDto {

    @ApiModelProperty(example = "post id")
    private Long id;
    @ApiModelProperty(example = "글제목")
    private String title;
    @ApiModelProperty(example = "글쓴이")
    private String author;
    @ApiModelProperty(example = "글내용")
    private String content;
    @ApiModelProperty(example = "글 생성날짜")
    private LocalDateTime createdAt;
    @ApiModelProperty(example = "글 수정날짜")
    private LocalDateTime modifiedAt;
}

RequestDto를 사용한다면 해당 클래스에 똑같이 작성하면 된다.

@ApiImplicitParams 사용 예시

@ApiImplicitParam는 컨트롤러를 통해 받는 파라미터의 명이 무엇이고 파라미터 값은 어떤 의미인지를 명세해준다.

    @GetMapping(path = "/api/posts/{id}")
    @ApiOperation(value = "게시글 조회", notes = "게시글을 조회한다.")
    @ApiImplicitParam(name = "id", value = "Post Entity Id값")
    public PostResponseDto getPost(@PathVariable Long id) {
        return postService.getPost(id);
    }

마냥 파라미터가 2개 이상이라면 @ApiImplicitParams어노테이션을 다음과 같이 사용하여 여러 Param들을 명시해주면 된다.

    @PostMapping(path = "/api/posts")
    @ApiOperation(value = "게시글 작성", notes = "게시글을 작성한다.")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "title", value = "제목"),
            @ApiImplicitParam(name = "author", value = "글쓴이"),
            @ApiImplicitParam(name = "password", value = "비밀번호"),
            @ApiImplicitParam(name = "content", value = "내용")
    })
    public Long createPost(@Valid @RequestBody PostRequestDto postRequestDto) {
        return postService.create(postRequestDto);
    }

반드시 필요하지 않은 선택적인 파라미터를 가지고 있다면 required 옵션을 사용하면 된다.

 @ApiImplicitParam(name = "title", value = "제목",required = false)

@ApiIgnore

만약 컨트롤러나, 메소드, 파라미터 등의 설명이 굳이 필요하지 않고 문서에 표시하고 싶지 않다면 @ApiIgnore를 사용하면 된다.

@ApiResponses 사용예시

@ApiResponses 는 여러 개의 @ApiResponse담으며 반환값 코드와 그에 맞는 메세지를 지정하여 설명해준다.

    @ApiResponses({
            @ApiResponse(code=200, message="글목록 조회 완료"),
            @ApiResponse(code=401, message="조회 권한 없음. 로그인 필요"),
            @ApiResponse(code=500, message="서버 에러")
    })
    @GetMapping(path = "/api/posts")
    @ApiOperation(value = "전체 게시글 목록 조회", notes = "전체 게시글 목록을 조회한다.")
    public List<PostResponseDto> getPosts() {
        return postService.getPostsList();
    }

정리

Swagger를 사용해봄으로써 정말 말도안되는 생산성 증대가 된다고 생각한다. 매번 API를 수정할 때마다 문서를 수정하는 일이 쉽지 않다고 느끼는데 이런 불편함을 한번에 해결해 주어 놀라웠다. 개발 공부를 하고 있는 분들이라면 꼭 한번 사용해보시면서 REST API 공부에 도움이 되셨으면 좋겠다.

'Web Dev' 카테고리의 다른 글

[Github] 개발자 Github Profile 정리 팁  (0) 2022.10.25
서버 Elasticsearch 설치 테스트  (0) 2022.09.05
러버덕 디버깅 이야기  (0) 2022.08.17
AWS EC2 Redis 세팅 해보기  (0) 2022.08.04
객체지향처럼 생각하기  (0) 2022.07.21