들어가면서
API 문서를 수정하는 것은 좀 귀찮다. API 수정 사항이 있으면 문서를 수정하고 코드도 수정하고 두 번 수정을 해야 하는데
코드의 의도가 자동으로 문서에 반영되면 한 번의 코드 수정으로 문서까지 수정할 수 있다.
이런 수요 때문에 API 자동화 도구들이 생기게 된 것이 아닌가 싶다.
그중에서 Swagger는 사용자 친화적인 예쁜 UI를 가지고 있고 문서에서 직접 API 요청을 만들 수 있어서 매우 유용하다.
Spring에서 이 Swagger를 통합해서 사용할 수 있도록 개발된 라이브러리를 이용해서 API를 자동화를 구현해 보자.
장점
- 예쁜 UI
- 확장성이 좋다.
- 문서에서 HTTP 요청 생성 가능
단점
- 코드가 오염돼서 로직을 파악하기가 힘들다.
- 자동으로 생성되었지만 개발자의 실수로 문서의 내용이 틀릴 수 있다.
설정 방법
글 작성일을 기준으로 최신 버전을 사용했다.
build.gradle
에 해당 의존성을 추가한다.
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'
- 스프링을 가동한 이후에 다음 url로 접근하면 swagger 문서를 볼 수 있다.
http://localhost:8080/swagger-ui/index.html
접근 경로를 변경하거나 하는 설정은 공식 문서에서 살펴보자.
Intro 명세
처음 API 명세서를 보여주는 소개글을 적을 수 있다.
이를 위해서 Swagger 설정을 해주는 OpenAPI
클래스 빈을 등록하면 된다.
- 예시
@Bean
public OpenAPI openAPI(@Value("${springdoc.version}") String appVersion){
Info info=new Info()
.title("내일배움캠프 익명 게시판 서버 만들기")
.version(appVersion)
.description("이렇게 하는거 맞나요?")
.contact(new Contact()
.name("donggeun yu")
.url("https://github.com/yudonggeun")
.email("ydong98@gmail.com"))
.license(new License()
.name("Apache License Version 2.0")
.url("http://www.apache.org/licenses/LICENSE-2.0")
);
return new OpenAPI()
.components(new Components())
.info(info);
}
이런 설정을 하면 다음 결과물이 나온다.
Parameter 명세
파라미터의 명세를 나타내기 위해서는 @Parameter
어노테이션을 사용한다.
파라미터 어노테이션에 정의된 속성을 사용해서 문서를 만들어주면 된다.
속성 | 설명 |
---|---|
name | 실제 요청에서 사용하는 파라미터의 변수의 이름을 설정하는 속성 |
description | 문서에서 어떤 파라미터인지 설명하는 속성 |
example | 가상의 요청을 생성할 때 사용되는 기본값 |
required | 필수값 여부를 나타내는 값 |
- 예시 1
@Parameter(name = "id", description = "게시글 id", required = true)
- 예시 2
@Parameters({
@Parameter(name = "size", description = "페이지 사이즈 default : 10", example = "10", required = true),
@Parameter(name = "page", description = "페이지 인덱스 default : 0", example = "0"),
})
Request 명세
Request Header 명세 (Authorization)
스프링 시큐리티를 적용하면 필터에서 header를 통해서 인가 여부를 확인할 수 있는데.. 이때 swagger를 통해서 인증 헤더를 문서화하는 방법을 알아보자.
다음 그림은 swagger 문서에서 인증/인가 스키마에 대한 목록이다. 이러한 인증 방법은 @SecurityScheme 어노테이션을 통해서 문서 자동화를 구현할 수 있다. 예제는 JWT 토큰 인증을 문서화를 다루었다.
1. 헤더에 사용되는 인가 헤더 정의하기
@Configuration
@SecurityScheme(
name = "Bearer Authentication",
type = SecuritySchemeType.HTTP,
bearerFormat = "JWT",
scheme = "bearer"
)
public class SwaggerConfig {
}
스웨거 설정 클래스에서 인증/인가 헤더를 정의한다.
2. 컨트롤러에 적용하기
@SecurityRequirement(name = "Bearer Authentication")
정의된 인증 헤더를 적용하기 위해서 다음 어노테이션을 원하는 메서드나 클래스 단위에 적용하면 문서에 반영된다.
Request Body 명세
Http 요청의 body 부분에서 json 형태의 데이터를 받을 때, dto 객체를 선언해서 매핑을 한다.
dto 타입으로 사용하는 객체에 @Scheme
어노테이션을 사용해서 문서를 만든다.@Scheme
어노테이션은 스키마(골격)에 대한 명세를 만들어주어서 문서에 적용해 준다.
속성 | 설명 |
---|---|
description | 문서에서 어떤 값인지 설명하는 속성 |
example | 가상의 요청을 생성할 때 사용되는 기본값 |
- 예시
public record UpdateBoardRequest(
@Schema(description = "게시글 id", example = "1")
Long id,
@Schema(description = "게시글 제목", example = "고양이 좋아")
String title,
@Schema(description = "작성자", example = "현실일상님")
String author,
@Schema(description = "비밀번호", example = "1234")
String password,
@Schema(description = "게시글 내용", example = "근데 댕댕이가 더 좋아")
String content
) {
}
Response Body 명세
응답 역시 @Scheme
를 사용해서 명세를 작성하지만 응답은 사용자의 요청에 따라서 서버의 상태에 따라서 다른 응답을 하는 경우가 있다.
이를 문서에 녹이기 위한 방법이 필요한데 이것이 ApiResponse
이다.
속성 | 설명 |
---|---|
responseCode | 응답 상태 코드를 설정하는 속성 ( ex: 200, 404 ) |
description | 어떤 상황에 반환되는 응답인지 설명 |
content | 응답시 어떤 컨텐츠(body)를 반환하는지에 대한 정보 |
headers | 응답 헤더 관련 정보 |
여기 content 속성에는 @Content
정보를 입력하는데 이 어노테이션의 schema 속성에 @Schema
를 사용해서
어떤 상황에서 이런 응답을 하는지 문서화할 수 있다.
- 예시
// FailResponse 는 만든 클래스
@ApiResponses({
@ApiResponse(responseCode = "200", description = "로그인 성공"
headers = @Header(name = "Authorization", description = "Bearer jwt 토큰을 정보입니다.")),
@ApiResponse(responseCode = "400", description = "필수 정보 누락",
content = @Content(schema = @Schema(implementation = FailResponse.class))),
@ApiResponse(responseCode = "403", description = "비밀번호가 잘못됨",
content = @Content(schema = @Schema(implementation = FailResponse.class))),
})
Global Setting
이렇게 문서화를 위한 어노테이션을 설정했지만 contentType이 application/json으로 문서에 반영되지 않았다.
각 API 요청마다 커스텀하는 방법도 있지만 이번에 만드는 서버는 API 서버이기 때문에 글로벌 설정으로 반영을 했다.
- 예시
springdoc:
default-consumes-media-type: application/json
default-produces-media-type: application/json
사용법
만든 API 문서는 특별한 설정을 하지 않는다면 http://localhost:8080/swagger-ui/index.html을 통해서 조회할 수 있다.
만들어진 문서에서 아래의 그림처럼 HTTP 요청을 만들어서 바로 서버에게 요청할 수 있고 데이터를 바꾸어서 요청할 수도 있어서 편하게 테스트를 할 수 있다.
Result
완성된 결과물 코드 저장소다.
ISSUE
1. ControllerAdvice로 처리한 전체 예외 처리 전략이 모든 API의 문서에 기록되는 문제
@Hidden 어노테이션을 사용하면 문제를 해결할 수 있다.
Reference
v1버전의 스택을 v2에서 통합해서 도움이 된다.
'spring' 카테고리의 다른 글
Spring 메일 전송기능 구현하기 (3) | 2023.12.01 |
---|---|
커스텀 Validation annotation 만들기 (1) | 2023.11.13 |
Spring Rest docs 와 Swagger 장점만 골라서 사용하기 (0) | 2023.10.28 |
RestTemplate을 통해서 API 호출하기 (0) | 2023.10.13 |
[WebFlux] Spring WebFlux 란 무엇인가? (0) | 2023.06.22 |