Posts [Swagger] Open API 3.0 Swagger v3 상세설정
Post
Cancel

[Swagger] Open API 3.0 Swagger v3 상세설정

※ 실습 프로젝트는 Github에서 확인 할 수 있습니다.

Api문서를 쉽게 알아보기 위해선 Schemas 에 대한 설명과 들어갈 값에 대한 정보가 필요하다. 또한 api method에 대한 설명도 있어야 api구성 목록을 원활하게 식별할 수 있다.

이번 포스팅에서는 Swagger v3 Annotation을 이용하여 API 문서의 설명을 구체적으로 작성하고, Java Bean Validation 을 이용하여 api 사용시 유효성 체크를 하도록 한다.

1) api 그룹 설정: @Tag

Target: ANNOTATION_TYPE, METHOD, TYPE

  • name: 태그의 이름
  • description: 태그에 대한 설명

Tag에 설정된 name이 같은 것 끼리 하나의 api 그룹으로 묶는다. 주로 Controller나 Controller의 Method 영역에 설정한다.

1
2
3
4
5
6
@Tag(name = "posts", description = "게시물 API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/")
public class PostsApiController {
    ...

PostsController에 @Tag를 설정해 보았다.

스크린샷 2021-09-02 오후 10 31 58

@Tag 어노테이션 설정 한 후 Swagger UI 화면이다. 설정한 태그명과 설명이 각 태그에 표시되었다.

2) api Schema 설정 : @Schema

Target : ANNOTATION_TYPE, FIELD, METHOD, PARAMETER, TYPE

  • description : 한글명
  • defaultValue : 기본값
  • allowableValues :

Schmea(= Model)에 대한 정보를 작성하는 곳이다. Schema를 설정할 시, 더욱 완성도 높은 Swagger UI 문서를 만들 수 있다. 아래 이미지는 @Schema 설정을 하지 않은 dto클래스들의
모델 정보이다.

스크린샷 2021-09-02 오후 10 35 18

각 필드값들에 대한 설명이나 기본값, 허용가능한 값 등에 대한 정보 없이 string 요소가 들어간다는 정보 뿐이라 모호하다. api 문서의 완성도를 높이기 위해서는 @Schema 설정을 통해 어떤 값들이 들어가는지 설정을 추가해주는 것이 좋다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Schema(description = "게시물 리스트 응답DTO")
@Getter
public class PostsListResponseDto {
    @Schema(description = "일자")
    private Long id;

    @Schema(description = "게시물 제목", defaultValue = "디폴트 제목", allowableValues = {"게시물1", "게시물2"})
    private String title;

    @Schema(description = "내용")
    private String content;

    @Schema(description = "수정일자")
    private LocalDateTime modifiedDate;

    public PostsListResponseDto(Posts posts) {
        this.id = posts.getId();
        this.title = posts.getTitle();
        this.content = posts.getContent();
        this.modifiedDate = posts.getModifiedDate();
    }
}

스크린샷 2021-09-02 오후 10 40 17

스키마 적용 후 swagger-ui 화면

@Schema 적용을 마친 후의 PostsListResponseDto 모델의 정보이다. 좀 더 자세하게 스키마에 대한 정보를 확인 할 수 있게 된다.

참고 블로그 필자 분은 아래와 같이 스키마를 지정하였다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Schema(description = "사용자")
@Getter @Setter
public class UserValue {

	@Pattern(regexp = "[0-2]")
	@Schema(description = "유형", defaultValue = "0", allowableValues = {"0", "1", "2"})
	private String type;

	@Email
	@Schema(description = "이메일", nullable = false, example = "abc@jiniworld.me")
	private String email;

	@Schema(description = "이름")
	private String name;

	@Pattern(regexp = "[1-2]")
	@Schema(description = "성별", defaultValue = "1", allowableValues = {"1", "2"})
	private String sex;

	@DateTimeFormat(pattern = "yyMMdd")
	@Schema(description = "생년월일", example = "yyMMdd", maxLength = 6)
	private String birthDate;

	@Schema(description = "전화번호")
	private String phoneNumber;

	@Schema(description = "비밀번호")
	private String password;

}

Model 클래스에 대한 한글명을 설정하였고(첫번째 라인) 각 필드값에 대한 설정을 하였다. 또한 description에 한글명을 작성하고, defaultValue를 통해 기본값을 제공하였다. 그리고 allowableValues를 설정하여 Schema 정보에서 리스트 형태로 들어갈 수 있는 데이터 정보를 볼 수 있게 하였다.

만일, Validation 체크를 하고 싶다면 javax.validation.constraints 패키지를 이용하면 된다. 특정 Regex를 이용하여 패턴체크를 하고 싶다면 Pattern을 이용하면 된다.

3 참고 블로그 작성자분의 캡처 화면

3) api 상세 정보 설정 : @Operation

Target: ANNOTATION_TYPE, METHOD

  • summary: api에 대한 간략한 설명
  • description: api에 대한 상세 설명
  • response: api Response 리스트
  • parameters: api 파라미터 리스트

@Operation어노테이션은 api동작에 대한 명세를 작성하기 위해 Controller 메소드에 설정한다.

Swagger UI가 fold상태일때도 간략히 확인할 수 있는 간략정보는 summary에 작성하고, 필요에 따라 상세 정보를 표기하고자 한다면 description에 설명을 추가하면 된다.

responses는 아래에서 설명할 @ApiResponse 리스트들 설정하는 요소이다. parameters는 path, query, header, cookie 등의 형태로 들어오는 파라미터에 대한 정보를 설정하는 요소이다.

아래는 save메소드의 @Operation을 지정하는 코드이다.

1
2
3
4
5
@PostMapping("/posts")
@Operation(summary = "게시물 등록", description = "제목(title)과 내용(content)을 이용하여 게시물을 신규 등록합니다.")
public Long save(@RequestBody PostsSaveRequestDto dto) {
    return postsService.save(dto);
}

위와 같이 @Operation 어노테이션을 지정하면 아래 이미지 처럼 swagger-ui에서 Controller메소드에 대한 정보(설명글 및 파라미터 정보 등등)를 더 자세하게 확인 할 수 있게 된다.

4

4) api response 설정 : @ApiResponse

Target: ANNOTATION_TYPE, METHOD, TYPE

  • responseCode: http 상태코드
  • description: response에 대한 설명
  • content: Response payload 구조
    • schema: payload에서 이용하는 Schema
      • hidden: Schema 숨김 여부
      • implementation: Schema 대상 클래스

@ApiResponse 는 응답 결과에 따른 response 구조를 미리 확인할 수 있게 해준다.

만약 @ApiResponse를 지정하지 않으면 아래 이미지처럼 Swagger UI에서는 상태코드 200과 비어있는 response body를 보여준다.

스크린샷 2021-09-02 오후 11 00 47

무늬뿐인 response 구조가 아닌, api 조회 성공 및 실패시 발생될 상태코드 및 Response 구조를 설정하고자 한다면 @ApiResponse를 설정하면 된다.

게시글 조회 API에 @ApiResponse 어노테이션을 추가해보자.

테스트 애플리케이션의 게시글 조회 API에서는 200, 404 상태코드가 설정되어 있다. 조회가 성공되었을 시, 200 상태코드와 PostsResponseDto클래스가 reseponseBody에 반환되고 조회 실패시엔, 404 상태코드와 ErrorResponse클래스가 responseBody가 반환됩니다.

implementation 에 responseBody로 제공될 클래스의 Class 타입을 반환해야하는데, 이때 주의해야할 점은 implementation에는 class literal 타입만 들어갈 수 있다는 점입니다.

1
2
3
4
5
6
7
8
@ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "게시글 조회 성공", content = @Content(schema = @Schema(implementation = PostsResponseDto.class))),
        @ApiResponse(responseCode = "404", description = "존재하지 않는 리소스 접근", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) })
@Operation(summary = "게시글 조회", description = "id를 이용하여 posts 레코드를 조회합니다.")
@GetMapping("/posts/{id}")
public PostsResponseDto findById(@PathVariable Long id) {
    return postsService.findById(id);
}

@ApiResponse 리스트는 @ApiResponses 에 담아 api method에 설정해도 되고,

1
2
3
4
5
6
7
8
@Operation(summary = "게시글 조회", description = "id를 이용하여 posts 레코드를 조회합니다.", responses = {
        @ApiResponse(responseCode = "200", description = "게시글 조회 성공", content = @Content(schema = @Schema(implementation = PostsResponseDto.class))),
        @ApiResponse(responseCode = "404", description = "존재하지 않는 리소스 접근", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
})
@GetMapping("/posts/{id}")
public PostsResponseDto findById(@PathVariable Long id) {
    return postsService.findById(id);
}

@Operation의 responses 요소에 설정해도 된다. 위와 같이 적용하고 swagger-ui를 실행하면 아래와 같은 결과를 확인할 수 있다.

5

5) api parameter 설정 : @Parameter

Target: ANNOTATION_TYPE, FIELD, METHOD, PARAMETER

  • name: 파라미터 이름
  • description: 파라미터 설명
  • in: 파라미터 위치
    • query, header, path, cookie

@ApiResponse와 마찬가지로 @parameters 어노테이션에 @Parameter 리스트를 담아 api메서드에 설정할 수 있고, @Operation 어노테이션에 parameters 요소에 설정할 수도 있다.

그리고 파라미터의 경우 api method의 인자 값에 붙여 명시적으로 설정할 수도 있다.

@Parameters 나 @Operation에 설정하는 방법은 @ApiResponse에서와 유사하므로, 이번에는 method 인자값에 붙이는 방법을 예제로 살펴보자.

1
2
3
4
5
6
7
8
9
@Operation(summary = "게시글 조회", description = "id를 이용하여 posts 레코드를 조회합니다.", responses = {
        @ApiResponse(responseCode = "200", description = "게시글 조회 성공", content = @Content(schema = @Schema(implementation = PostsResponseDto.class))),
        @ApiResponse(responseCode = "404", description = "존재하지 않는 리소스 접근", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
})
@GetMapping("/posts/{id}")
public PostsResponseDto findById(@Parameter(name = "id", description = "posts 의 id", in = ParameterIn.PATH)
                                        @PathVariable Long id) {
    return postsService.findById(id);
}

path로부터 들어올 파라미터인 id에 대한 설정을 추가하였다. @PathVariable 설정 앞에 @Parameter 어노테이션 설정을 추가했는데, 메서드의 인자앞에 직접 설정할 경우에는 name을 생략할 수 있다.

만일 @Parameters 나 @Operations에 파라미터를 설정할 경우에는 어떤 파라미터에 대한 설정인지 알 수 없기 때문에 반드시 name을 설정해 줘야 한다.

실행 결과 Swagger-ui는 아래 이미지에서 확인 할 수 있다.

6

출처

This post is licensed under CC BY 4.0 by the author.