1. 개요 Overview
REST API를 만들 때 문서화를 잘하는 것은 중요하다.
더우기 API를 변경할 때마다 레퍼런스 문서에 똑같이 명시해주어야한다. 이것을 수작업으로 반영하는 것은 매우 지루한 일이므로, 이것을 자동화하는 것은 필수다.
이 튜토리얼에서 우리는 스프링 REST 웹서비스를 위한 스웨거 2 Swagger 2 for a Spring REST web service를 들여다 볼것이다. 이 문서에서 스웨거 2 명세서의 구현체인 Springfox를 사용할 것이다.
스웨거에 익숙하지않은 사용자라면 먼저 이 글을 읽기전에 공식웹페이지를 방문해보기를 권한다.
2. 타겟 프로젝트 Target Project
REST서비스 생성은 이 문서의 범주가 아니므로 사용자는 이미 간단히 적용할만한 프로젝트를 가지고 있어야 한다. 아직 없다면 다음의 링크가 좋은 출발점이 될 것이다:
3. 메이븐 의존성 추가 Adding the Maven Dependency
위에서 언급한 것처럼 우리는 스웨거 명세서의 스프링 폭스 구현체를 사용할 것이다. 메이븐 프로젝트의 pom.xml파일에 다음의 의존성을 추가하자.
1 2 3 4 5 | < dependency > < groupId >io.springfox</ groupId > < artifactId >springfox-swagger2</ artifactId > < version >2.2.2</ version > </ dependency > |
4. 프로젝트에 스웨거 2 통합하기 Integrating Swagger 2 into the Project
4.1. 자바 설정 Java Configuration
스웨거의 설정은 주로 Docket 빈 설정에 중심을 둔다:
1 2 3 4 5 6 7 8 9 10 11 12 | @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build(); } } |
스웨거 2는 @EnableSwagger2 어노테이션 설정으로 사용가능해진다.
Docket 빈을 정의한 후, 그 select() 메소드는 ApiSelectorBuilder 인스턴스를 리턴하는데 이는 스웨거에 의해 노출되는 끝단endpoint 을 제어하는 하나의 방법을 제공해준다.
RequestHandlers 의 selection을 위한 서술부는 RequestHandlerSelectors 와 PathSelectors 의 도움을 받아 설정할 수 있다. 둘 다 any() 를 쓰면 사용자의 전체 API가 스웨거를 통해 문서화 되어질 것이다.
이 설정을 통해 기존의 스프링 부트 프로젝트에 스웨거 2를 통합할 수 있다. 다른 종류의 스프링 프로젝트에서는 몇가지 추가적인 작업을 해주어야한다.
4.2. 스프링 부트 없이 설정하기 Configuration Without Spring Boot
스프링 부트를 사용하지 않는다면 사용자는 리소스 핸들러의 자동설정 혜택을 받을 수 없다. 스웨거 UI는 리소스의 세트를 추가하는 데 이는 사용자가 @EnableWebMvc 어노테이션을 가지는, WebMvcConfigurerAdapter 를 확장한 하나의 클래스와 일부로서 설정해주어야 한다.
1 2 3 4 5 6 7 8 | @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler( "swagger-ui.html" ) .addResourceLocations( "classpath:/META-INF/resources/" ); registry.addResourceHandler( "/webjars/**" ) .addResourceLocations( "classpath:/META-INF/resources/webjars/" ); } |
4.3. 검증 Verification
스프링폭스가 동작하는지 검증하려면 다음의 URL을 브라우저로 접속해보자:
http://localhost:8080/your-app-root/v2/api-docs
가독성이 매우 낮은 key-value페어를 가진 수많은 JSON응답을 볼 수 있는데, 다행히 스웨거는 이를 위해 스웨거 UI를 제공해준다.
5. 스웨거 UI Swagger UI
스웨거 UI는 스웨거가 생성하는 API문서를 사용자 대화방식으로 더 쉽게 만들어주는 내장 솔루션이다.
5.1. 스프링폭스의 스웨거 UI 사용하기 Enabling Springfox’s Swagger UI
스웨거 UI를 사용하려면, 하나의 추가적인 메이븐 의존성 필요하다.:
1 2 3 4 5 | < dependency > < groupId >io.springfox</ groupId > < artifactId >springfox-swagger-ui</ artifactId > < version >2.2.2</ version > </ dependency > |
이제 사용자는 브라우저에서 다음의 링크에 접속하여 테스트할 수 있다 - http://localhost:8080/your-app-root/swagger-ui.html
다음과 같은 페이지가 보여질 것이다:
5.2. 스웨거 문서 둘러보기 Exploring Swagger Documentation
이제 사용자의 어플리케이션에 정의된 모든 컨트롤러의 리스트가 보여질 것이다. 그들중 하나를 클릭하면 유효한 HTTP 메소드 (DELETE, GET, HEAD, OPTIONS, PATCH,POST, PUT)를 리스트해준다.
각 메소드를 확장해보면 응답상태response status, 컨탠트타입content-type 그리고 파라메터 리스트와 같은 추가적인 유용한 데이터를 제공해준다. 또한 UI를 통해 각각의 메소드를 테스트할 수있다.
사용자의 코드와 동기화 되어 있는 스웨거의 능력은 매우 중요하다. 이를 증명하기 위해, 새 컨트롤러를 어플리케이션에 추가해보자:
1 2 3 4 5 6 7 8 | @RestController public class CustomController { @RequestMapping (value = "/custom" , method = RequestMethod.POST) public String custom() { return "custom" ; } } |
이제 스웨거 문서를 새로고침해보면, 컨트롤러 리스트에서 custom-controller 를 볼 수 있을 것이다. 위에서 만든것처럼 POST 메소드 하나만 보여질 것이다.
6. 고급 설정 Advanced Configuration
사용자 어플리케이션의 Docket 빈에서 사용자가 API 문서를 생성하는데 더 많은 설정이 가능하다.
6.1. 스웨거의 응답코드에 API 필터링하기 Filtering API for Swagger’s Response
사용자 API 전체를 문서화하는 것은 보통 바람직한 방법은 아니다. 사용자는 Docket 클래스의 apis() 와paths() 에 파라메터를 넣어줌으로서 스웨거의 응답코드를 제한할 수 있다.
위에서 봤듯이 RequestHandlerSelectors 는 any or none 서술을 허용하지만 base package, class annotation, 그리고 method annotations에 기초하여 API 를 필터링할 수도 있다.
PathSelectors 는 사용자 어플리케이션의 요청경로request paths를 스캔하는 서술문들 통해 추가적인 필터링을 제공해주는데 any(), none(), regex(), 또는 ant() 를 사용할 수 있다.
아래의 예제에서 우리는 ant() 서술어를 사용하여 스웨거가 특정 패키지, 특정 경로에 있는 컨트롤러만 포함하도록 하였다.
1 2 3 4 5 6 7 8 | @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage( "org.baeldung.web.controller" )) .paths(PathSelectors.ant( "/foos/*" )) .build(); } |
6.2. 커스텀 정보 Custom Information
스웨거는 또한 응답코드를 사용자가 “Api Documentation”, “Created by Contact Email”, “Apache 2.0” 와 같은 정보를 커스터마이즈 할 수 있는 몇가지 기본값을 제공해준다.
이 값들을 수정하려면 apiInfo(ApiInfo apiInfo) 메소드를 사용하면 된다. ApiInfo 클래스는 API에 대한 커스텀 정보를 포함하고 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage( "com.example.controller" )) .paths(PathSelectors.ant( "/foos/*" )) .build() .apiInfo(apiInfo()); } private ApiInfo apiInfo() { ApiInfo apiInfo = new ApiInfo( "My REST API" , "Some custom description of API." , "API TOS" , "Terms of service" , "myeaddress@company.com" , "License of API" , "API license URL" ); return apiInfo; } |
6.3. 커스텀 메소드 응답 메세지 Custom Methods Response Messages
스웨거는 Docket의 globalResponseMessage() 메소드를 통해 HTTP 메소드의 전역적 오버라이딩 응답메세지 globally overriding response messages of HTTP methods 를 허용한다. 먼저 스웨거가 기본 응답메시지를 쓰지않도록 설정해주어야한다.
모든 GET 메소드에 대한 500 와 403 응답 메시지를 오버라이드하려면, Docket 의 초기화 블럭에 약간의 코드를 추가해주어야한다. (초기화 코드는 여기서 제외하였다):
1 2 3 4 5 6 7 8 9 10 11 | .useDefaultResponseMessages( false ) .globalResponseMessage(RequestMethod.GET, newArrayList( new ResponseMessageBuilder() .code( 500 ) .message( "500 message" ) .responseModel( new ModelRef( "Error" )) .build(), new ResponseMessageBuilder() .code( 403 ) .message( "Forbidden!" ) .build())); |
7. 결론 Conclusion
이 튜토리얼에서 우리는 스프링 REST API의 문서를 생성해주는 스웨거2를 설정하였다. 또한 스웨거의 산출물을 시각화하고 커스터마이즈하는 방법들을 알아보았다.
이 튜토리얼의 전체 구현은 다음의 github 프로젝트에서 확인할 수 있다 – 이클리스 기반이며 임포트해서 쉽게 돌려볼 수 있다.