[ Spring ]/REST API

[Spring] Rest API Documentation을 위한 Swagger 사용

쿠릉쿠릉 쾅쾅 2022. 5. 10. 22:30
728x90

 

Swagger

Swagger를 사용하면 애노테이션 코드 몇 줄을 추가하여 간단하게 API별로 문서화 및 API 테스트 가능한 UI 까지 제공하여 문서 작성 시간을 단축하여 개발에 집중할 수 있다.
Swagger는 API들이 가지고 있는 스펙(spec)을 명세, 관리할 수 있는 문서다.
Springboot에서 Swagger를 사용하면 컨트롤러에 명시된 애노테이션을 해석하여 API문서를 자동으로 만들어준다.

  • http://localhost:8080/v2/api-docs
  • http://localhost:8080/swagger-ui/

🔍 Gradle 의존성 추가

https://mvnrepository.com/artifact/io.springfox/springfox-boot-starter

dependencies {
    implementation 'io.springfox:springfox-boot-starter:3.0.0'
}

🔍 Swagger 3.x.x 버전 호환 이슈 해결

📌 yml

spring:
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher

string boot 2.6.x 버전과 swagger 3.x.x 간에 호환 이슈가 있기에 ymsl 파일에 추가로 설정해야한다.

🔍 Swagger 설정 class 생성

📌 SwaggerConfig

@EnableSwagger2 
@Configuration 
public class SwaggerConfig { 
    @Bean 
    public Docket api() { 
        return new Docket(DocumentationType.SWAGGER_2) 
                .select() 
                .apis(RequestHandlerSelectors.any()) // 특정 패키지경로를 API문서화 한다. 1차 필터 
                .paths(PathSelectors.any()) // apis중에서 특정 path조건 API만 문서화 하는 2차 필터 
                .build() 
                .groupName("API 1.0.0") // group별 명칭을 주어야 한다. 
                .pathMapping("/") 
                .apiInfo(apiInfo()) 
                .useDefaultResponseMessages(false); // 400,404,500 .. 표기를 ui에서 삭제한다. 
    } 
    private ApiInfo apiInfo() { 
        return new ApiInfoBuilder() 
                .title("fantoo_api_test 프로젝트") 
                .description("API 호출 테스트용도.") 
                .version("1.0.0") 
                .termsOfServiceUrl("") 
//                .contact() 
                .license("") 
                .licenseUrl("") 
                .build() 
                ; 
    } 
}

🔍 Swagger-ui 실행

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

🔍 Swagger 사용 설명

@EnableSwagger2 : Swagger2 버전을 활성화하겠다는 애노테이션

Docket

  • Swagger 설정을 할 수 있게 도와주는 클래스다.
  • API 자체에 대한 스펙은 컨트롤러에서 작성한다.
  • 설정 메서드
    • useDefaultResponseMessages(boolean apply)
      • 파라미터를 false로 설정하면 swaager에서 제공해주는 응답코드(200, 401, 405, 404)에 대한 기본 메시지를 제거한다.
      • 불필요한 응답코드와 메시지를 제거하기 위함이다. 컨트롤러에서 명시한다.
    • groupName(String groupName)
      • Docket Bean이 한 개 인 경우 기본값은 default이므로 생략 가능
      • Docket Bean이 여러개인 경우 groupName이 충돌하지 않아야하므로 파라미터를 각 Docket Bean 버전으로 사용할 것을 권장한다.
    • select()
      • ApiSelectorBuilder를 생성하여 apis() 메서드와 paths()를 사용할 수 있게 해준다.
    • apis()
      • api 스펙이 작성되어 있는 패키지를 지정한다.
      • 즉, 컨트롤러가 존재하는 패키지를 basepackage로 지정하여 해당 패키지에 존재하는 API를 문서화 한다.
    • paths()
      • apis() 로 선택되어진 API 중 특정 path 조건에 맞는 API들을 다시 필터링하여 문서화한다.
      • PathSelectors.any() 로 설정하면 패키지 안에 모든 API를 한 번에 볼 수 있다.
    • apiInfo(ApiInfo apiInfo)
      • 제목, 설명 등 문서에 대한 정보를 주기 위해 호출한다.

ApiInfo 파라미터 정보

🔍 컨트롤러

@Api

  • 해당 클래스가 Swagger의 리소스라는 것을 명시한다.
    • value
      • 사용자 지정 이름을 붙일 수 있다. tags 속성 사용시 무시된다.
    • tags
      • 여러 개의 태그를 정의할 수 있다.

@ApiOperation

  • 한 개의 Operation(API URL, Method)을 선언한다.
    • value
      • API에 대한 간략한 설명(제목같은 느낌)을 작성한다.
    • notes
      • 더 자세한 설명을 작성한다. 

@ApiResponse

  • operation의 가능한 response를 명시한다.
    • code
      • 응답 코드 작성
    • message
      • 응답에 대한 설명 작성
    • responseHeaders
      • 헤더 추가

@ApiParam

  • 파라미터에 대한 정보를 명시한다.
    • value
      • 파라미터 정보 작성
    • required
      • 필수 파라미터면 true, 아니면 false를 작성
    • example
      • 테스트를 할 때 보여줄 예시를 작성한다.

 

 

🔍 사용 예시

📌 User

@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(description = "사용자 상제 정보를 위한 도메인 객체")
public class User {

    private Long id;

    @Size(min = 2, message = "Name은 2글자 이상 입력해 주세요.")
    @ApiModelProperty(notes = "사용자의 이름을 입력해 주세요.")
    private String name;

    @Past  // 과거 날짜만 가능하도록 제약
    @ApiModelProperty(notes = "사용자의 등록일을 입력해 주세요.")
    private LocalDateTime joinDate;

    @ApiModelProperty(notes = "사용자의 비밀번호를 입력해 주세요.")
    private String password;
    @ApiModelProperty(notes = "사용자의 주민번호을 입력해 주세요.")
    private String ssn; // 주민등록번호

}

@ApiModel / @ApiModelProperty를 이용하여 각 필드에 추가정보를 작성할 수 있다.

📌 SwaggerConfig

@Configuration
@EnableSwagger2
public class SwaggerConfig{

    /**
     * ApiInfo, Contct를 직접 new 연산자로 만들어도 되고 builder로 생성해도 된다.
     * new 연산자로 직접 생성하여 정적으로 생성하면 GC에 의해서 지워지지 않으므로 메모리 낭비가 없다.
     */
//    private static final Contact DEFAULT_CONTACT = new Contact("name1", "http://www.aa.com", "abc@naver.com");
//    private static final ApiInfo DEFAULT_API_INFO =
//            new ApiInfo("Awesome API Title", "My User management REST API service", "1.0", "urn:tos", DEFAULT_CONTACT, "Apache 2.0", "http://www.age.", new ArrayList<>());

    private static final Set<String> DEFAULT_PRODUCES_AND_CONSUMES
            = new HashSet<>(Arrays.asList("application/json", "application/xml"));

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .groupName("그룹그룹")
                .produces(DEFAULT_PRODUCES_AND_CONSUMES)  // Http 요청시 어떤 문서 타입을 지정할 수 있는지
                .consumes(DEFAULT_PRODUCES_AND_CONSUMES)  // 응답 객체 반환시 어떤 문서 타입으로 반환할 지
                ;
    }

    // ApiInfoBuilder로 생성하기
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Awesome Api Title")
                .description("API 호출 테스트 용도")
                .version("1.0.0")
                .termsOfServiceUrl("unr:tos")
                .contact(new Contact("이름이름", "주소주소", "이메일이메일"))
                .license("Apache 2.0!!")
                .licenseUrl("http://www.naver.com")
                .build()
                ;
    }
}

 

 

 

 


👀 참고 자료

https://velog.io/@dkatlf900/swagger

 

Swagger API DOC 구축부터 실행까지

Spring Boot REST API, Swagger 구축.

velog.io

 

https://doozi316.github.io/web/2020/10/16/WEB29/

 

Swagger란?

 

doozi316.github.io

 

https://velog.io/@banjjoknim/Swagger

 

Swagger로 API 문서 자동화를 해보자

Swagger라는 툴을 사용해서 API를 문서화 해보자.

velog.io

 

https://victorydntmd.tistory.com/341

 

[SpringBoot] Swagger - API Docs 자동화

1. API Docs가 필요한 이유 - Swagger란? 본인이 맛집 서비스를 구현한다고 가정해봅시다. 그러면 대한민국 지도 데이터( 도/시, 군/구, 읍/면/동 ), 마커 표시 (위도/경도, 아이콘 ) 등을 모두 구현해야

victorydntmd.tistory.com

 

https://www.baeldung.com/swagger-apiparam-vs-apimodelproperty

 

Swagger @ApiParam vs @ApiModelProperty | Baeldung

Learn the difference between Swagger's @ApiParam and @ApiModelProperty

www.baeldung.com

 

728x90