前言
通過之前的兩篇文章,可以簡單的搭建一個路由網關了。而我們知道,現在都奉行
前后端分離
開發,前后端開發的溝通成本就增加了,所以一般上我們都是通過swagger
進行api文檔生成的。現在由於使用了統一路由網關了,都希望各微服務的api文檔
統一的聚合在網關服務中,也方便前端用戶查閱,不需要每個服務單獨查看。當然了,也是可以做一個文檔索引網頁進行各微服務的api文檔鏈接的。今天,我們就來講下使用swagger
實現自動化聚合微服務文檔功能。
注:關於Swagger
的介紹和使用,由於在之前的SpringBoot
系列文章中有提及,這里就不在過多闡述了,不理解的可以點擊:第十章:Swagger2的集成和使用進行查看,了解下基本用法。
Zuul聚合示例
為了實現自動聚合功能,簡單來說就是通過Zuul
api獲取所有的路由信息,根據其具體地址進行自動轉配到Swagger
的SwaggerResource
下。
另外,為了項目的獨立,本章節創建個maven
多模塊工程項目。整體結構如下:
同時,會啟動一個基於Eureka
的注冊服務,具體可以查看源碼:spring-cloud-eureka-server。
微服務端
為了演示,創建兩個微服務spring-cloud-zuul-service-one
和spring-cloud-zuul-service-two
。
這里以構建spring-cloud-zuul-service-one
為例,spring-cloud-zuul-service-two
基本上是一樣的,可以查看源碼示例。
0.引入相關依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 客戶端依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.0</version>
</dependency>
1.編寫swagger配置類。
/**
* swagger配置類
* @author oKong
*
*/
@EnableSwagger2
@Configuration
public class SwaggerConfig {
//是否開啟swagger,正式環境一般是需要關閉的,可根據springboot的多環境配置進行設置
@Value(value = "${swagger.enabled}")
Boolean swaggerEnabled;
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
// 是否開啟
.enable(swaggerEnabled).select()
// 掃描的路徑包
.apis(RequestHandlerSelectors.basePackage("cn.lqdev.learning.springcloud.zuul.service"))
// 指定路徑處理PathSelectors.any()代表所有的路徑
.paths(PathSelectors.any()).build().pathMapping("/");
}
//設置api信息
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("路由網關(Zuul):利用swagger2聚合API文檔-service-one")
.description("oKong | 趔趄的猿")
// 作者信息
.contact(new Contact("oKong", "https://blog.lqdev.cn/", "499452441@qq.com"))
.version("1.0.0")
.build();
}
}
2.編寫控制層,設置對外api服務信息,同時創建了請求和響應的實體類。
DemoController.java
/**
* demo示例
* @author oKong
*
*/
@RestController
@Api(tags="servicie-one服務")
@Slf4j
public class DemoController {
@GetMapping("/hello")
@ApiOperation(value="demo示例")
public DemoResp hello(DemoReq demoReq) {
log.info("DemoReq:{}", demoReq);
return DemoResp.builder()
.code(demoReq.getCode())
.name(demoReq.getName())
.remark(demoReq.getRemark())
.build();
}
}
DemoReq.java
/**
* 請求實體
* @author oKong
*
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel
public class DemoReq {
@ApiModelProperty(name="code",value="編碼",example="oKong")
String code;
@ApiModelProperty(name="name",value="名稱",example="趔趄的猿")
String name;
@ApiModelProperty(name="remark",value="備注",example="blog:blog.lqdev.cn")
String remark;
}
DemoResp.java
/**
* 響應實體
* @author Okong
*
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel
public class DemoResp {
@ApiModelProperty(name="code",value="編碼",example="oKong")
String code;
@ApiModelProperty(name="name",value="名稱",example="趔趄的猿")
String name;
@ApiModelProperty(name="remark",value="備注",example="blog:blog.lqdev.cn")
String remark;
}
3.編寫啟動類。
/**
* api服務1 示例
* @author oKong
*
*/
@SpringBootApplication
@EnableDiscoveryClient
@Slf4j
public class ServiceOneApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(ServiceOneApplication.class, args);
log.info("spring-cloud-zuul-service-one啟動!");
}
}
4.添加配置信息。
spring.application.name=api-service-one
server.port=789
# 注冊中心地址 -此為單機模式
eureka.client.service-url.defaultZone=http://127.0.0.1:1000/eureka
# 啟用ip配置 這樣在注冊中心列表中看見的是以ip+端口呈現的
eureka.instance.prefer-ip-address=true
# 實例名稱 最后呈現地址:ip:2000
eureka.instance.instance-id=${spring.cloud.client.ip-address}:${server.port}
# swagger開關
swagger.enabled=true
5.啟動應用,訪問:http://127.0.0.1:789/swagger-ui.html 就可以單應用api文檔配置成功了
路由網關端
創建項目:spring-cloud-zuul-gateway
關於zuul的使用,可以查看:第九章:路由網關(Zuul)的使用
0.引入相關依賴。
<!-- zuul 依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<!-- 客戶端依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.0</version>
</dependency>
1.添加相關配置信息。
spring.application.name=zuul-gateway
server.port=8899
# 注冊中心地址 -此為單機模式
eureka.client.service-url.defaultZone=http://127.0.0.1:1000/eureka
# 啟用ip配置 這樣在注冊中心列表中看見的是以ip+端口呈現的
eureka.instance.prefer-ip-address=true
# 實例名稱 最后呈現地址:ip:15678
eureka.instance.instance-id=${spring.cloud.client.ip-address}:${server.port}
# swagger開啟開關
swagger.enabled=true
2.編寫swagger配置類(重點)
@EnableSwagger2
@Configuration
@Primary //多個bean時 此類優先使用
public class SwaggerConfig implements SwaggerResourcesProvider{
//是否開啟swagger,正式環境一般是需要關閉的,可根據springboot的多環境配置進行設置
@Value(value = "${swagger.enabled}")
Boolean swaggerEnabled;
@Autowired
RouteLocator routeLocator;
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
// 是否開啟
.enable(swaggerEnabled).select()
// 掃描的路徑包
.apis(RequestHandlerSelectors.basePackage("cn.lqdev.learning.springcloud.zuul.swagger2"))
// 指定路徑處理PathSelectors.any()代表所有的路徑
.paths(PathSelectors.any()).build().pathMapping("/");
}
//設置api信息
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("路由網關(Zuul):利用swagger2聚合API文檔")
.description("oKong | 趔趄的猿")
// 作者信息
.contact(new Contact("oKong", "https://blog.lqdev.cn/", "499452441@qq.com"))
.version("1.0.0")
.termsOfServiceUrl("https://github.com/xie19900123/")
.build();
}
@Override
public List<SwaggerResource> get() {
//利用routeLocator動態引入微服務
List<SwaggerResource> resources = new ArrayList<>();
resources.add(swaggerResource("zuul-gateway","/v2/api-docs","1.0"));
//循環 使用Lambda表達式簡化代碼
routeLocator.getRoutes().forEach(route ->{
//動態獲取
resources.add(swaggerResource(route.getId(),route.getFullPath().replace("**", "v2/api-docs"), "1.0"));
});
//也可以直接 繼承 Consumer接口
// routeLocator.getRoutes().forEach(new Consumer<Route>() {
//
// @Override
// public void accept(Route t) {
// // TODO Auto-generated method stub
//
// }
// });
return resources;
}
private SwaggerResource swaggerResource(String name,String location, String version) {
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
swaggerResource.setSwaggerVersion(version);
return swaggerResource;
}
}
這里繼承SwaggerResourcesProvider
接口是實現聚合api的關鍵,另外通過RouteLocator
類獲取路由
列表是實現自動聚合的關鍵。
當然,這里也是可以手動進行添加的。
3.編寫zuul內部控制層。
/**
* zuul 內部提供對外服務示例
* @author oKong
*
*/
@RestController
@RequestMapping("/demo")
@Api(tags="zuul內部rest api")
public class DemoController {
@GetMapping("/hello")
@ApiOperation(value="demo示例",notes="demo示例")
@ApiImplicitParam(name="name",value="名稱",example="oKong")
public String hello(String name) {
return "hi," + name + ",this is zuul api! ";
}
}
4.編寫啟動類。
/**
* zuul使用swagger2聚合微服務api示例
* @author oKong
*
*/
@SpringBootApplication
@EnableZuulProxy
@EnableDiscoveryClient
@Slf4j
public class ZuulSwaggerApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(ZuulSwaggerApplication.class, args);
log.info("spring-cloud-zuul-gateway啟動!");
}
}
5.啟動應用,訪問:http://127.0.0.1:8899/swagger-ui.html 可以看見頁面顯示的是網關項目的swagger
文檔信息。
現在看看右上角的Select a spec
下拉框,可以看見下拉框中包含了注冊中心下的所有微服務了。
此時,我們切換下api-service-one
,可以看見api-service-one
的api列表了。
切換到api-service-two
,也可以看見都要的api列表信息。
參考資料
總結
本章節主要簡單介紹了如何在
Zuul
路由網關服務利用Swagger2
進行微服務api的聚合功能。這樣查看各微服務的api文檔就很方便,集中,不需要在切換不同文檔地址了。
最后
目前互聯網上大佬都有分享
SpringCloud
系列教程,內容可能會類似,望多多包涵了。原創不易,碼字不易,還希望大家多多支持。若文中有錯誤之處,還望提出,謝謝。
老生常談
- 個人QQ:
499452441
- 微信公眾號:
lqdevOps
個人博客:http://blog.lqdev.cn
源碼示例:https://github.com/xie19900123/spring-cloud-learning
以下教程可能你會感興趣:
- SpringBoot | 第十章:Swagger2的集成和使用
- 白話SpringCloud | 第九章:路由網關(Zuul)的使用
- 白話SpringCloud | 第十章:路由網關(Zuul)進階:過濾器、異常處理
原文地址:https://blog.lqdev.cn/2018/10/19/SpringCloud/chapter-eleven/