Springr기반 웹어플리케이션, 정확히는 API 어플리케이션을 만들때 API의 테스트와 Documentation의 자동화를 위해 Swagger라이브리를 적용하게 된다.
라이브러리를 추가하고 필요한 엔드포인트 ( 클래스 레벨일 수도 있고, 메서드 레벨일 수도 있다)에 어노테이션으로 정의를 해주면 Swagger가 제너레이션 해주는 특정 웹페이지를 통해 API의 테스트 뿐만이 아니라, 세련된 UI로 웹기반의 API 도큐먼트를 만들어 준다.
의존성 라이브러리는 아래와 같이 두 개의 라이브러를 추가해 주면 된다. (Gradle 기준)
build.gradle 파일의 일부
// https://mvnrepository.com/artifact/io.springfox/springfox-swagger2
implementation group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'
// https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui
implementation group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2'
스프링부트의 환경설정
@Profile({"local","dev"})
@EnableSwagger2
@Configuration
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("io.lpin.maa"))
.paths(PathSelectors.ant("/v1/api/**")) // /v1/api/** 인 URL들만 필터링
.build()
.apiInfo(apiInfo())
.enable(true)
;
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("API 타이틀")
.description("API 상세소개 및 사용법 등")
.version("1.0")
.build();
}
}
기존의 @Configuration 클래스 파일에 @EnableSwagger2 어노테이션을 추가하고, Docket 유형의 빈등록을 간단하게 해주면 Swagger로 온라인 도큐먼트를 구성하는 최소한 작업이 끝난다.
물론, 공통헤더의 설정 및 보안에 관련된 상세 설정들을 가능하지만, 주제와 벗어나서 다루지 않겠다.
개인적으로 Configuration 클래스들은 용도에 맞게 분리해서 관리하는게 효율적이라고 생각한다. 실제로 운영을 하다보면 각각의 설정들을 변경해야 하거나, 더 이상 특정 설정값들이 필요없어질때 작업하기가 훨씬 수월하다.
- 데이타 소스 설정
- 쓰레드관리, 스케쥴링 서비스 관련 (Batch Job)
- Web MVC 설정 및 Security 설정 ( Spring MVC, Spring Security )
- Swagger, Cache(Redis)등의 서드파티 라이브러리의 설정
보통은 이런 영역들은 설정파일을 따로 두고 관리하는게 어플리케이션을 관리하는데 용이하다.
위의 코드중 유심히 봐야 할 어노테이션이 있다.
코드 최상단의 '@Profile({"local","dev"})' 이 부분이다.
API 온라인 도큐먼트의 경우, 상용서비스로 익명에게 공개할 API가 아닐 수 있다. 개발자가 로컬용으로 정말 '테스트'용으로만 사용할 목적이거나 특정시점까지는 내부적으로 테스트만 해야 하는 상황일 수 있다.
이럴 경우, @Profile 어노테이션을 이용해서 프로덕트 프로파일에서는 Swagger 설정이 적용되지 않도록 처리가 가능하다.
물론, Swagger설정뿐만이 아니라 @Configuration 이 붙어있는 설정 클래스들은 이 Profile 어노테이션을 모두 사용할 수 있다.
글의 주제에서 좀 벗어나 버렸는데,
이 글에서 얘기하려고 하는 내용은 Swagger가 생성하는 페이지인 swagger-ui.html이 접근이 안되고 404 Not Found 에러가 발생하는 경우가 있다. 별개 아닌 이슈이기는 하지만, 이유를 모르면 이런 단순한 이슈 때문에 쓸데 없이 시간을 낭비할 수 있을까봐 혹시나 도움이 될 까봐 글을 남긴다.
springfox의 swagger2 (2.9.x)를 사용하는 경우 발생하는 현상인데 이럴 경우,
스프링부트의 Configuration을 통해 ResourceHandler를 오버라이드해서 swagger-ui.html 페이지가 어디에 있는지 위치를 추가해줘야 한다.
이전 버전에서는 별도의 설정이 필요없었던걸로 기억하는데, 이 설정이 되어 있지 않으면 swagger-ui.html을 찾을 수 없다는 에러가 발생하니, springfox의 swagger 라이브러리를 사용하는 경우 아래의 설정을 꼭 추가하도록 하자.
@Configuration
@EnableSwagger2
public class SwaggerConfig extends WebMvcConfiguarationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
...
...
}
-
WebMvcConfiguarationSupport 상속받아 addResourceHandlers 메서드를 오버라이딩 해야한다.
참고로 SpringFox의 Swagger 라이브러는 아직까지 API의 정렬(ordering 또는 position )해주는 어노테이션을 지원하지 않고 있다.
API를 컨트롤러 클래스별로의 정렬과 컨트롤러내에서 순서에 맞는 API들의 정렬이 꼭 필요한데, 이 단순한 기능을 제공하지 않는 게 이해가 잘 되지 않는다.
보통, tag 어노테이션을 활용해서 정렬을 하기는 하는데 완벽하게 내가 원하는 대로 API들을 정렬해 주지는 못한다.
적당한 수준과 목적으로 잘 활용한다면,
스프링 부트 기반 API 서비스를 개발하는데 있어 Swagger는 꽤 유용한 라이브러리가 될 수 있을 것이라 생각한다.
기회가 된다면, SprigFoc의 Swagger가 지원하는 어노테이션에 대해서 상세하게 다루어 보도록 하겠다.
최근댓글