白話SpringCloud | 第十一章:路由網關(Zuul):利用swagger2聚合API文檔


前言

通過之前的兩篇文章,可以簡單的搭建一個路由網關了。而我們知道,現在都奉行前后端分離開發,前后端開發的溝通成本就增加了,所以一般上我們都是通過swagger進行api文檔生成的。現在由於使用了統一路由網關了,都希望各微服務的api文檔統一的聚合在網關服務中,也方便前端用戶查閱,不需要每個服務單獨查看。當然了,也是可以做一個文檔索引網頁進行各微服務的api文檔鏈接的。今天,我們就來講下使用swagger實現自動化聚合微服務文檔功能。

注:關於Swagger的介紹和使用,由於在之前的SpringBoot系列文章中有提及,這里就不在過多闡述了,不理解的可以點擊:第十章:Swagger2的集成和使用進行查看,了解下基本用法。

Zuul聚合示例

為了實現自動聚合功能,簡單來說就是通過Zuulapi獲取所有的路由信息,根據其具體地址進行自動轉配到SwaggerSwaggerResource下。

另外,為了項目的獨立,本章節創建個maven多模塊工程項目。整體結構如下:

項目結構

同時,會啟動一個基於Eureka的注冊服務,具體可以查看源碼:spring-cloud-eureka-server

微服務端

為了演示,創建兩個微服務spring-cloud-zuul-service-onespring-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文檔配置成功了

service-one-swagger

路由網關端

創建項目: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文檔信息。

zuul-gate-swagger-ui

現在看看右上角的Select a spec下拉框,可以看見下拉框中包含了注冊中心下的所有微服務了。

Select a spec

此時,我們切換下api-service-one,可以看見api-service-one的api列表了。

api-service-one

切換到api-service-two,也可以看見都要的api列表信息。

api-service-two

參考資料

  1. https://piotrminkowski.wordpress.com/2017/04/14/microservices-api-documentation-with-swagger2/

總結

本章節主要簡單介紹了如何在Zuul路由網關服務利用Swagger2進行微服務api的聚合功能。這樣查看各微服務的api文檔就很方便,集中,不需要在切換不同文檔地址了。

最后

目前互聯網上大佬都有分享SpringCloud系列教程,內容可能會類似,望多多包涵了。原創不易,碼字不易,還希望大家多多支持。若文中有錯誤之處,還望提出,謝謝。

老生常談

  • 個人QQ:499452441
  • 微信公眾號:lqdevOps

公眾號

個人博客:http://blog.lqdev.cn

源碼示例:https://github.com/xie19900123/spring-cloud-learning

以下教程可能你會感興趣:

原文地址:https://blog.lqdev.cn/2018/10/19/SpringCloud/chapter-eleven/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM