Spring

[Spring] Spring Boot 프로젝트에서 Swagger로 API 문서 관리

Unan 2023. 5. 1. 19:14
반응형

Spring Boot 프로젝트를 하면서, API 문서를 정리하기 위해 Swagger를 사용하면서 알게 된 점들을 정리했다.

 

Swagger는 대표적인 API 명세서 Tool이다.

Notion 혹은 Postman 혹은 엑셀 등등… 을 이용해서 API 명세서를 관리하는 것 역시 좋지만,

이러한 API의 경우 API에 수정사항이 생겼을 때, 관리하기 어려운 점이 있습니다.

 

개발 후에 명세서 작성을 놓치는 경우도 있고, 개발한 code와 API 명세서가 다른 Human Error가 생기는 경우도 빈번하게 있습니다…

(JSON key 하나만 잘못 써도 요청이 제대로 안들어가니까요..)

따라서 API 명세서를 code로 관리하면, 조금 더 편리하고 오류 없이 관리할 수 있습니다…

그래서 사용하는 것이 Swagger라는 Tool입니다.

Spring Boot 2 버전에서 Swagger 설정

Spring Boot 2.x 버전에서 Spring Boot Project를 만들 떄는 springfox에서 만든 Swagger 라이브러리를 이용하여, Swagger를 연동했다.

하지만 springfox의 경우 업데이트가 진행되지 않고 있고, Spring Boot 3 버전에서 연동하는데 오류가 있었다.

 

Swagger 구현

아래 링크는 Swagger를 구현한 springdoc 공식 문서입니다.

 

Swagger의 장점

  1. Code와 함께 API 명세서를 관리할 수 있다.
  2. 다양한 프레임워크에서 지원
  3. 제가 여태 개발했던 프레임워크 Django, FastAPI, express, Nest JS, spring에서 모두 지원했습니다…
  4. 일관되고 깔끔한 UI
  5. UI 자체도 깔끔하고, 봤을 때 잘 구분이 되어있어 확인하기 좋습니다.
  6. API Test 가능

Swagger의 단점

  1. Code가 지저분해진다.
  2. 결국 API 명세서를 확인하려면 API가 구현이 되어야 확인할 수 있습니다. → 따라서 Swagger를 사용하더라도, 문서로 미리 API 명세서를 작업해두는 것을 추천드립니다.

 

Spring Boot 3 버전에서 Swagger 설정

  • springfox가 최근에 업데이트가 되지 않아서인지, 같은 설정을 이용하여 spring boot 3버전에 붙였을 때, 실행이 잘 되지 않았다.
  • 그래서 찾아보던 중 springdoc을 이용하면, Spring Boot 3버전에서도 잘 실행되는 것을 확인할 수 있었다.

Swagger를 사용하면서 언급하는 대표적인 단점으로 Code상에 API 문서를 작성하는 형태이기 때문에, 가독성이 많이 떨어진다는 것이다.

특히 Annotation 기반으로 Controller에 명세서를 작성하다 보면, 매우 코드가 지저분해져서 실제 Controller code를 찾아가기 힘든 경우 들도 있었다.

이와 관련해서 크게 세 가지 방향성이 있었다

첫번째로는 RestDocs를 사용하는 것이다.

  • 기존에는 Swagger의 UI가 깔끔하고, API Test도 용이하여 Swagger를 사용하는 것을 선호했지만 RestDocs를 사용하면 Test Code를 강제할 수 있다는 점이 이점이라고 생각했다.

두번째로는 RestDocs로 작성한 Test Code를 컴파일하여 api docs 파일을 Swagger UI로 띄우는 것이다. 관련해서는 블로그 레퍼런스를 찾아 진행했다.

마지막으로 Controller에 직접 코드를 집어넣지 않고, Controller의 Interface를 만들어 interface에 API 문서를 작성하고, Controller는 해당 class를 implements 하는 형태로 리팩토링 하는 것이다.

  • 해당 방식의 경우, Controller에는 깔끔하게 code를 정리할 수 있기 때문에 Swagger를 사용하는 상황에서는 최선의 선택지라는 생각이 들었다.

https://springdoc.org/

 

OpenAPI 3 Library for spring-boot

Library for OpenAPI 3 with spring boot projects. Is based on swagger-ui, to display the OpenAPI description.Generates automatically the OpenAPI file.

springdoc.org

 

Swagger를 사용하기 위해서 아래 의존성을 추가해주겠습니다.

 

dependencies { 
	implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0' 
 }

 

 

@Configuration
@SecurityScheme(
        name = "JWT Authentication",
        type = SecuritySchemeType.HTTP,
        bearerFormat = "JWT",
        scheme = "bearer"
)
public class SwaggerConfig {

    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI()
                .info(new Info()
                        .title("Demo Server API")
                        .version("1.0.0")
                        .description("Demo Server API Docs"));
    }
}

 

 

또한 설정 파일 (application.yml)에도 설정을 추가하겠습니다.

springdoc:
  packages-to-scan: 프로젝트패키지
  default-consumes-media-type: application/json;charset=UTF-8
  default-produces-media-type: application/json;charset=UTF-8
  swagger-ui:
    tags-sorter: alpha
    operations-sorter: alpha
  api-docs:
    path: /api-docs/json
    groups:
      enabled: true

 

Annotation을 이용하여 ControllerDTO 에서 명세서를 작성해줄 수 있습니다.

 

아래는 DTO에 작성한 명세서 예시입니다.

 

@Data
@AllArgsConstructor
@Schema(description = "사용자 정보 응답 DTO")
public class MemberGetResponse {

    @Schema(description = "회원 프로필 이미지 url", example = "1")
    private String imageUrl;
    @Schema(description = "회원 닉네임", example = "unan")
    private String nickname;
}

 

아래는 Controller에 작성한 예시입니다.

 

@PatchMapping
@Operation(summary = "회원가입 API")
@Parameter(name = "Authorization", description = "Bearer {access_token}", in = ParameterIn.HEADER, required = true, schema = @Schema(type = "string"))
@ApiResponses( value = {
    @ApiResponse(responseCode = "204", description = "회원가입 성공"),
    @ApiResponse(responseCode = "400", description = "회원가입 실패", content = @Content),
    @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
public ResponseEntity<MemberCreateResponseDto> patchMember(@Valid @RequestBody MemberCreateV2RequestDto request, Principal principal) {
  return ResponseEntity.ok(memberService.updateV2(request, getMemberId(principal)));
}

 

이 외에 다양한 Option과 설정이 존재합니다. 공식 링크 Docs를 보면서 프로젝트에 알맞게 적용해보시면 좋을 것 같습니다.

 

Swagger를 사용할 때 주의할 점

Swagger를 통해서, 서버에서 구축한 API 명세서를 쉽게 확인할 수 있습니다…! → 내가 원하지 않는 누군가도 Swagger를 확인할 수 있겠죠?

따라서 운영 환경으로 배포하는 서버에서는 Swagger를 사용하지 않는 것이 좋습니다.

반응형

'Spring' 카테고리의 다른 글

[Study] Test Code Study 정리 (1)  (1) 2024.02.27
[Spring] AWS EC2에 Spring Boot Project 배포하기.  (0) 2023.06.05
[Spring Boot] Spring Boot로 HTTP API 설계하기  (2) 2023.05.10
[Spring] H2 Database 설정  (0) 2023.04.20
[Spring] Lombok  (0) 2023.04.19