Open API/Swagger

Open API - @ArraySchema 적용이 안 됨.

비뀨_ 2022. 10. 29. 01:58

이 글은 구동 원리가 아닌 문제 해결하는 하나의 방법을 제시할 뿐입니다. 

이유를 알고 있거나 더 좋은 의견이 있다면 꼭 댓글 부탁드립니다 ;ㅅ;

 

버전

springdoc-openapi-ui : 1.6.11

springdoc-openapi-data-rest : 1.6.11

문제 상황 

- 아래는 모집글(Post)의 전체 목록을 조회하려는 코드이다. 아래의 코드에서

PostSearchCondition 부분은 모집글 검색 조건을 설정하는 객체이다. PostSearchCondition 안에서 해당 컬럼들을 Open API 문서화시키고 있는데, 모집글에서 사용하는 기술 스택의 배열 부분이 아래 사진처럼 나오지 않는다.

 PostController

    @Operation(summary = "모집글 전체 목록", description = "모집글 List 조회")
    @Parameters(value = {
            @Parameter(name = "page", description = "현재 페이지. 0이상 정수",
                    in = ParameterIn.QUERY,
                    content = @Content(schema = @Schema(type = "integer", defaultValue = "0")), required = true),
            @Parameter(name = "size", description = "한 page 크기. 기본값 20. 0이상 정수.",
                    in = ParameterIn.QUERY,
                    content = @Content(schema = @Schema(type = "integer", defaultValue = "20")), required = false),
            @Parameter(name = "sort", description = "정렬 기준. 정렬기준이 여러개라면 sort=정렬기준,(ASC|DESC)&...으로 사용",
                    content = @Content(array = @ArraySchema(schema = @Schema(type = "string"))), required = false),
            @Parameter(name = "X-MOYEO-AUTH-TOKEN", description = "JWT 토큰",
                    in = ParameterIn.HEADER, required = false)
    })
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "success")
    })
    @GetMapping
    public Page<PostQueryDto> findPostAll(@Parameter(hidden = true) @PageableDefault(size = 20) Pageable pageable,
                                          @Parameter(hidden = true) @AuthenticationPrincipal UserToken userToken,
                                          @ParameterObject @ModelAttribute PostSearchCondition searchCondition) {
        String userId = "";
        if(userToken != null) {
            userId = userToken.getUserId();
        }
        return postService.findPostAll(pageable, userId, searchCondition);
    }

 

PostSearchCondition 객체

@Schema(description = "Request에서 넘어오는 검색조건 객체")
@Setter
@Getter
public class PostSearchCondition {
    @Schema(description = "제목")
    private String title;
    @Schema(description = "모집상태", defaultValue = "RECRUITING")
    private RecruitStatus status;
    @ArraySchema(schema = @Schema(type = "Long", name = "skillId", description = "기술스택 ID"))
    private List<Long> skillList;
}

 

@ArrayScheme 을 통해서 기술 스택 Id의 목록을 정의하고 싶어서 ArraySchema를 통해 정의했는데 위의 문제 상황이 발생했다.

@ArraySchema의 어노테이션 안을 살펴보면 

해석하자면 ArraySchema 어노테이션은 OpenAPI 사양의 요소 집합에 대해 "배열" 유형의 스키마를 정의하거나 스키마에 대한 추가 속성을 정의하는 데 사용할 수 있습니다.

 

아니... 그러니까 List<Long> 형식의 스키마를 정의하고 싶어......

이번에 OpenApi를 사용한 적이 처음이라 구글링을 해보면서 적용하고 있는데 계속 이 부분이 막혀버린 것이다.

 

근데 자세히 살펴보면 PostController에서  PostSearchCondition 부분은 @ParameterObject 어노테이션을 사용했다.

 

간단하게 설명하자면

@ParameterObject 은 파라미터 객체를 의미한다.

실제적으로 내가 원한 검색 조건은 다음과 같이 @Get 방식으로 URL에서 Query 형식으로 넘어온다.

더보기

http://localhost:8081/post/?title=&recruitStatus=RECRUITING

때문에 PostSearchCondition은 파라미터 객체이기 때문에 @ParameterObject를 사용하는 게 맞다고 생각했다. 실제로도 skillList를 제외한 부분들에 대해서는 적용이 되는 것을 확인할 수가 있고.

근데 배열만 왜 안 되는 건지 의아했고

혹시 ParameterObject 속성을 사용했으니까 Parameter로 받으면 되지 않을까 싶어서 해보았다.

 

변경된 코드는 skillList 밖에 없기 때문에 위의 PostSearchCondition을 참고하세요.

변경된 PostSearchCondition의 skillList 

 

@Parameter(description = "기술스택 ID 배열", example = "[1, 6, 11, 55]", content = @Content(array = @ArraySchema(schema = @Schema(type = "int",format = "int64"))))
    private List<Long> skillList;

 

다시 실행시켜봤을 때에는

 

원하는 것의 70% 정도가 되었다. 

왜 70% 냐면 실제적으로 변경된 코드의 

이 부분이 type 적용이 안되었다. 

위의 사진에서는 array[int] 라고 적용이 되었지만 Long 타입으로 받아야 하기 때문에 format을 int64로 주었는데

해당 부분은 제대로 적용이 안되었다.

 

아직 왜 String, Enum 등 다른 부분에 있어서는 Schema 어노테이션이 적용이 되는데, Array에 대해서는 @ArraySchema이 안되는지 이해가 안 된다.

 

원론적인 부분에 대해서는 이번 스터디에서 처음 사용해본 것뿐이라 잘 모르기 때문에 

프론트엔드 분들과 협업을 하기 위해서는 Swagger에 대해서 다시 한번 공부해야 할 것 같다.