前言
通过之前的两篇文章, 可以简单的搭建一个路由网关了. 而我们知道, 现在都奉行前后端分离开发, 前后端开发的沟通成本就增加了, 所以一般上我们都是通过 swagger 进行 API 文档生成的. 现在由于使用了统一路由网关了, 都希望各微服务的 API 文档统一的聚合在网关服务中, 也方便前端用户查阅, 不需要每个服务单独查看. 当然了, 也是可以做一个文档索引网页进行各微服务的 API 文档链接的. 今天, 我们就来讲下使用 swagger 实现自动化聚合微服务文档功能.
注: 关于 Swagger 的介绍和使用, 由于在之前的 SpringBoot 系列文章中有提及, 这里就不在过多阐述了, 不理解的可以点击: 第十章: Swagger2 的集成和使用进行查看, 了解下基本用法.
Zuul 聚合示例
微服务端
路由网关端
参考资料
总结
最后
老生常谈
Zuul 聚合示例
为了实现自动聚合功能, 简单来说就是通过 Zuulapi 获取所有的路由信息, 根据其具体地址进行自动转配到 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 文档就很方便, 集中, 不需要在切换不同文档地址了.
最后
来源: https://www.cnblogs.com/okong/p/springcloud-eleven.html