마이크로서비스에서 뿐만 아니라 모든 시스템에서 REST API를 문서화 하는 것은 매우 중요합니다.
REST API란 사용자 뿐만 아니라 다른 모듈, 응용 프로그램, 개발자들이 사용 할 수 있는 공용 인터페이스 입니다.
어떠한 API를 개발한 사람은 보통 해당 API 사용자가 아닙니다.
따라서 실제 사용자(혹은 모듈)에게 문서화해서 보여주는 것이 매우 중요합니다.
그 중 가장 많이 알려진 방법이 Swagger 입니다.
JSON 또는 YAML 메타 데이터를 이용하여 다수의 REST API를 설명 할 수 있습니다.
하지만 JSON 또는 YAML으로 사용자에게 보여주는 것은 불편하고 보기 힘들기 때문에 그에 맞는 UI도 제공합니다.
UI를 통해서 단순히 REST API 명세만 보여주는 것이 아니라 실제로 호출하고 응답을 검사 할 수 있습니다.
2. 어플리케이션에 swagger dependency 추가
REST API를 명세로 만들 즉 swagger를 통해서 제공 될 어플리케이션을 만듭니다.
기존의 customer-service와 order-service를 이용합니다.
먼저 pom.xml에 dependency를 추가합니다.
<!--swagger 기능을 제공하는 dependency 입니다.-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!--swagger로 생성된 json 등의 정보를 ui로 보여주기 위한 dependency 입니다.-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
swagger 관련 config를 작성합니다.
importcom.google.common.base.Predicates;importio.swagger.annotations.Contact;importio.swagger.annotations.Info;importio.swagger.annotations.License;importio.swagger.annotations.SwaggerDefinition;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importspringfox.documentation.builders.PathSelectors;importspringfox.documentation.builders.RequestHandlerSelectors;importspringfox.documentation.spi.DocumentationType;importspringfox.documentation.spring.web.plugins.Docket;importspringfox.documentation.swagger2.annotations.EnableSwagger2;importstaticcom.sds.act.coe.customer.web.rest.ApiConstants.API_V1_BASE_PATH;@Configuration@EnableSwagger2@SwaggerDefinition( info = @Info(description ="MSA-COE-CUSTOMER", version ="1.0.0", title ="MSA-COE-CUSTOMER", termsOfService ="Term of Service", contact = @Contact( name ="Samsung SDS", url ="https://www.samsungsds.com/", email ="samsungsds@samsung.com"), license = @License(name ="Apache License Version 2.0", url ="https://www.apache.org/licenses/LICENSE-2.0") ))publicclassSwaggerConfig { @BeanpublicDocketapi() {returnnewDocket(DocumentationType.SWAGGER_2).select().apis(Predicates.not(RequestHandlerSelectors.basePackage("org.springframework.boot"))).apis(Predicates.not(RequestHandlerSelectors.basePackage("org.springframework.cloud")))// .paths(PathSelectors.regex(API_V1_BASE_PATH + "/.*")).paths(PathSelectors.any()).build(); }/* @SwaggerDefinition 어노테이션 말고 아래와 같은 방법으로 정의 할 수 있습니다. private ApiInfo getApiInfo() { StringVendorExtension vendorExtension1 = new StringVendorExtension("name1", "value1"); StringVendorExtension vendorExtension2 = new StringVendorExtension("name2", "value2"); List<VendorExtension> vendorExtensionList = new ArrayList<>(); vendorExtensionList.add(vendorExtension1); vendorExtensionList.add(vendorExtension2); return new ApiInfo( "This is swagger title", "This is swagger description.", "1.0.0", "TERMS OF SERVICE URL", new Contact("name","url","mail address"), "Samsung SDS", "www.samsungsds.com", vendorExtensionList ); } */}
위에서 보다시피 swagger api에 title, description, contact user 정보 등을 추가 할 수 있습니다.
swagger ui를 통해서 개발자가 작성한 REST API 명세를 사용자가 쉽게 이해 할 수 있지만 마이크로서비스아키텍처 안에서는 몇개의 어플리케이션이 있을지 모릅니다.
따라서 각각의 어플리케이션이 제공하는 swagger 정보를 취합하는 기능이 필요합니다.
zuul gateway를 이용하거나 별도의 서버를 이용하여 구현이 가능합니다.
먼저 동일하게 gateway에 dependency를 추가합니다.
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!--swagger로 생성된 json 등의 정보를 ui로 보여주기 위한 dependency 입니다.-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
customer 어플리케이션과 동일하게 SwaggerConfig 파일을 작성합니다.
importcom.google.common.base.Predicates;importio.swagger.annotations.Contact;importio.swagger.annotations.Info;importio.swagger.annotations.License;importio.swagger.annotations.SwaggerDefinition;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.context.annotation.Profile;importspringfox.documentation.builders.PathSelectors;importspringfox.documentation.builders.RequestHandlerSelectors;importspringfox.documentation.spi.DocumentationType;importspringfox.documentation.spring.web.plugins.Docket;importspringfox.documentation.swagger.web.UiConfiguration;importspringfox.documentation.swagger2.annotations.EnableSwagger2;@Profile("!prod")@Configuration@EnableSwagger2@SwaggerDefinition( info = @Info(description ="MSA-COE", version ="1.0.0", title ="MSA-COE", termsOfService ="Term of Service", contact = @Contact( name ="Samsung SDS", url ="https://www.samsungsds.com/", email ="samsungsds@samsung.com"), license = @License(name ="Apache License Version 2.0", url ="https://www.apache.org/licenses/LICENSE-2.0") ))publicclassSwaggerConfig { @BeanpublicDocketapi() {returnnewDocket(DocumentationType.SWAGGER_2).select().apis(Predicates.not(RequestHandlerSelectors.basePackage("org.springframework.boot"))).apis(Predicates.not(RequestHandlerSelectors.basePackage("org.springframework.cloud")))// .paths(PathSelectors.regex("/api/.*")).paths(PathSelectors.any()).build(); }}
여기서 눈여겨 볼 점은 @Profile 어노테이션인데 개발계, 운영계에 따라서 해당 swagger 기능을 닫아야 할 필요가 존재합니다. 따라서 해당 어노테이션을 사옹하면 spring active profile에 따라서 기능을 on/off 할 수 있습니다.