白话SpringCloud | 第十一章:路由网关(Zuul):利用swagger2聚合API文档
前言
通过之前的两篇文章,可以简单的搭建一个路由网关了。而我们知道,现在都奉行
前后端分离
开发,前后端开发的沟通成本就增加了,所以一般上我们都是通过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/
白话SpringCloud | 第十一章:路由网关(Zuul):利用swagger2聚合API文档的更多相关文章
- 白话SpringCloud | 第十章:路由网关(Zuul)进阶:过滤器、异常处理
前言 简单介绍了关于Zuul的一些简单使用以及一些路由规则的简单说明.而对于一个统一网关而言,需要处理各种各类的请求,对不同的url进行拦截,或者对调用服务的异常进行二次处理等等.今天,我们就来了解下 ...
- SpringCloud学习系列之六 ----- 路由网关Zuul基础使用教程
前言 在上篇中介绍了SpringCloud Config的完美使用版本,本篇则介绍基于SpringCloud(基于SpringBoot2.x,.SpringCloud Finchley版)中的路由网关 ...
- 玩转SpringCloud(F版本) 四.路由网关(zuul)
本篇文章基于: 01)玩转SpringCloud 一.服务的注册与发现(Eureka) 02) 玩转SpringCloud 二.服务消费者(1)ribbon+restTemplate 03) 玩转Sp ...
- 白话SpringCloud | 第零章:前言
说在前面 大清早醒来,觉得睡不着了.还是起来,写写博客.但最后发现关于SpringBoot的安全相关的还是比较多内容的,也比较专业,怕是一个多小时完不成的,也罢,那就来写写关于SpringCloud前 ...
- 白话SpringCloud | 第九章:路由网关(Zuul)的使用
前言 介绍完分布式配置中心,结合前面的文章.我们已经有了一个微服务的框架了,可以对外提供api接口服务了.但现在试想一下,在微服务框架中,每个对外服务都是独立部署的,对外的api或者服务地址都不是不尽 ...
- SpringCloud(5)路由网关Spring Cloud Zuul
一个简单的微服务系统如下图: 1.为什么需要Zuul Zuul很容易实现 负载均衡.智能路由 和 熔断器,可以做身份认证和权限认证,可以实现监控,在高流量状态下,对服务进行降级. 2.路由网关 继续前 ...
- springcloud(十一):服务网关Zuul高级篇
时间过的很快,写springcloud(十):服务网关zuul初级篇还在半年前,现在已经是2018年了,我们继续探讨Zuul更高级的使用方式. 上篇文章主要介绍了Zuul网关使用模式,以及自动转发机制 ...
- springCloud之路API路由网关Zuul
1.简介 简单的理解就是,相当于在所有服务的调用前加了一层防火墙, 主要就是对外提供服务接口的时候,起到了请求的路由和过滤作用,也因此能够隐藏内部服务的接口细节,提高系统的安全性: 官方文档:http ...
- 跟我学SpringCloud | 第九篇:服务网关Zuul初
SpringCloud系列教程 | 第九篇:服务网关Zuul初探 前面的文章我们介绍了,Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散 ...
随机推荐
- 【10.2.3】ArcGIS Runtime for Android搭建开发环境过程中问题具体解释
一.Visual Studio Ultimate2012安装过程问题 1.问题描写叙述 安装完毕后,您将看到一条消息,指示安装程序已完毕.但并非全部的功能具有已正确安装.以及下面警告消息: Micro ...
- saltstack平台基础
saltstack概述saltstack是基于python开发的一套C/S架构配置管理工具,使用SSL证书签方的方式进行认证管理底层使用ZeroMQ消息队列pub/sub方式通信 号称世界上最快的 ...
- loj #6235. 区间素数个数
#6235. 区间素数个数 题目描述 求 1∼n 1\sim n1∼n 之间素数个数. 输入格式 一行一个数 n nn . 输出格式 一行一个数,表示答案. 样例 样例输入 10 样例输出 4 样例解 ...
- 20165224 陆艺杰 Exp5 MSF基础应用
用自己的话解释什么是exploit,payload,encode Exploit是攻击的行为 Payload是一段植入目标机的简短的带功能的恶意代码 Encode是编码,用于更改恶意代码,编码特征码检 ...
- 不带 www 跳转 到 带 www 网站..
IIS: <rule name="已导入的规则 1-1" stopProcessing="true"> <match url="^( ...
- JAVASCRIPT 使用 && 和 || 完成 简写
123=='1234' && 'active' 为真时,返回 'active '...可以当成 三元运算符的简写形式哦. let val = val || 'active' ...
- R语言结果输出方法
输出函数:cat,sink,writeLines,write.table 根据输出的方向分为输出到屏幕和输出到文件. 1.cat函数即能输出到屏幕,也能输出到文件. 使用方式:cat(... , fi ...
- C++_类继承3-动态联编和静态联编
程序调用函数时,将使用哪个可执行代码块呢?编译器负责回答这个问题. 将源代码中的函数调用解释为特定的函数代码块被称为函数名联编(binding). 在C语言中,这非常简单,因为每个函数名对应一个不同的 ...
- wepsocket 了解一下
WebSocket协议是基于TCP的一种新的协议.WebSocket最初在HTML5规范中被引用为TCP连接,作为基于TCP的套接字API的占位符.它实现了浏览器与服务器全双工(full-duplex ...
- (找到最大的整数k使得n! % s^k ==0) (求n!在b进制下末尾0的个数) (区间满足个数)
题目:https://codeforces.com/contest/1114/problem/C 将b分解为若干素数乘积,记录每个素数含多少次方 b = p1^y1·p2^y2·...·pm^ym. ...