Coding/Back - Spring Framework

Spring API문서화 1/2 Swagger #Day19

꿀딴지- 2023. 9. 12. 17:51

API 문서화(=API 스펙/사양/Specification) : REST API 백엔드 애플리케이션에 요청을 전송하기 위해서 알아야 되는 청 정보(요청 URL(또는 URI), request body, query parameter 등)를 문서로 정리한 것

 

Spring에서 자주사용하는) API 문서 작성 방법

  1. Spring rest docs
    1. 테스트코드에 annotation 작성(테스트코드가 전부 통과되어야 함)
      • 테스트코드를 짜야하므로 바로 결과를 보기는 어렵다
      • 문서의 역할만 함
  2. Swgger
    1. 컨트롤러 클래스에서 annotation 형태 - java에서도 많이 사용
      • 가독성이 떨어짐
      • 간편하게 문서화할 수 있음
      • 문서에서 바로 테스트 가능

 

Swagger : http://localhost:8080/swagger-ui/

1. Swagger 설정하기

  • dependencies 추가
dependencies {...
	implementation 'io.springfox:springfox-boot-starter:3.0.0'
  implementation 'io.springfox:springfox-swagger-ui:3.0.0'
}
  • application.yml 추가
spring:
	mvc:
	  pathmatch:
	     matching-strategy: ant_path_matcher
  • config class 추가
@Configuration
public class SwaggerConfig {

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .useDefaultResponseMessages(true) // Swagger 에서 제공해주는 기본 응답 코드 (200, 401, 403, 404) 등의 노출 여부
                .apiInfo(apiInfo()) // Swagger UI 로 노출할 정보
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.example._0907_pjt_blog.controller")) // api 스펙이 작성되어 있는 패키지 (controller)
                .paths(PathSelectors.any()) // apis 에 위치하는 API 중 특정 path 를 선택
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Swagger 문서 제목")
                .description("Swagger 문서 설명")
                .version("1.0")
                .build();
    }
}

2. Annotation 추가

<Controller 클래스>

  1. 컨트롤러 이름 설정 : 클래스 @Api(tags={"POST"}, description="게시글 관리") //되도록 대문자로
  2. 각 API별 설정 작성 : 메서드 @ApiOperation(value="게시글 작성", notes="게시글 신규로 생성하는 API 설명")
  3. 파라미터 설명 작성 : 메서드-파라미터 @ApiParam(value="게시글 작성정보")
  4. path 파라미터 설명 작성 : @ApiImplicitParam( name = "articleId", value = "게시글id", required = true, example = "1", dataType = "String", paramType = "path", defaultValue = "None" )
    • 오류 발생 : java.lang.NumberFormatException: For input string: "”
    • Integer 나 int 등 숫자(Number) 타입으로 된 필드나 매개변수에서 발생하는 것으로, 컨트롤러 내 메서드의 ApiImplicitParam 속성 중 example 속성에 값을 주면 됨
  5. Response 설명 : @ApiResponses({ @ApiResponse(code=200, message="성공"), @ApiResponse(code=401, message="접근 권한이 없습니다.") })

<DTO 클래스>

  • DTO 클래스 : @ApiModel(value="게시글 생성 요청 dto")
  • 파라미터 : @ApiModelProperty(value="게시글 title", example = "제목1", required = true)
//Controller 클래스

@Api(tags={"POST"}, description="게시글 관리")
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class ArticleApiController {
    private final ArticleService articleService;
    private final ArticleMapper mapper;

    //게시글 생성
    @ApiOperation(value="게시글 작성", notes="게시글 신규로 생성하는 API 설명")
    @PostMapping("/new")

    public ResponseEntity postArticle(@ApiParam(value="게시글 작성정보", required = true) @RequestBody ArticlePostDto articlePostDto){
        Article mappedArticle = mapper.articlePostDtoToArticle(articlePostDto);
        //Article mappedArticle = ArticlePostDto.articlePostDtoToArticle(articlePostDto);
        articleService.createArticle(mappedArticle);
        return new ResponseEntity(HttpStatus.CREATED);
    }

    //게시글 업데이트
    @ApiOperation(value="게시글 수정", notes="게시글 수정API 입니다.")
    @ApiImplicitParam(
            name = "articleId",
            value = "게시글id",
            required = true,
            example = "1",
            dataType = "String",
            paramType = "path",
            defaultValue = "None"
    )
    @ApiResponses({
            @ApiResponse(code=200, message="성공"),
            @ApiResponse(code=401, message="접근 권한이 없습니다.")
    })
    @PatchMapping("/{articleId}")
    public ResponseEntity updateArticle(@PathVariable("articleId") long articleId, @RequestBody ArticlePatchDto articlePatchDto){
        articlePatchDto.setArticleId(articleId);
        Article article = articleService.updateArticle(mapper.articlePatchDtoToArticle(articlePatchDto));
        return new ResponseEntity(HttpStatus.OK);
    }

}
//DTO 클래스

@ApiModel(value="게시글 생성 요청 dto")
@Getter
public class ArticlePostDto {
    @ApiModelProperty(value="게시글 title", example = "제목1", required = true)
    private String title;
    private String content;
    @Setter
    private String loginId;

참고 1. springfox : https://github.com/springfox/springfox

참고2. https://velog.io/@kijrary/Spring-Boot-프로젝트Gradle-에서의-Swagger-3.0.0-설정-방법

참고 3. https://chanos.tistory.com/entry/Spring-API-문서-자동화를-위한-Swagger-300-적용