「初学者商城」- 接口 - 聚合 Swagger(优化)

1. 前言


在「初学者商城」- 搭建基础架构(接口)# 7.3.1 Swagger 处有提到后续要聚合显示Swagger,这里终于得到了实现。

为什么要聚合显示?

  • 目前是每个工程都有一个/swagger-ui.html的入口,就导致:
    • 很麻烦,每一个服务工程都要记住对应的地址和端口号
    • 不安全,鉴权等操作都写在网关;并且在部署的时候也不会对外暴露内部服务工程的端口
    • 不完整,从中间某一环直接请求可能导致出现脏数据

达到的效果

  • 只需访问网关的/swagger-ui.html页面,就能切换到不同服务工程的接口文档

2. 源码


完整项目地址:https://github.com/intomylife/osc-api

v1.4.2 标签地址:https://github.com/intomylife/osc-api/releases/tag/v1.4.2

v1.4.2 下载地址:zip,tar.gz

注:对于标签的说明「初学者商城」- 写在最前面 #5.1


3. 接口


注:查看更改内容:聚合 Swagger

3.1 聚合的思路

访问每一个服务工程的/swagger-resources接口(http://localhost:8080/swagger-resources,http://localhost:8081/swagger-resources),发现返回的信息都是[{"name":"default","url":"/v2/api-docs","swaggerVersion":"2.0","location":"/v2/api-docs"}]

这是一个什么接口:用来获取Swagger的资源信息

我们跟着返回信息中的url地址走一个,新开页面访问 http://localhost:8080/v2/api-docs,发现返回的是基础工程中所有接口的描述信息(json 格式)

所以在网关中把基础工程和日志工程的/swagger-resources资源信息整合在一起后,是否就能达到想要的效果呢。答案是肯定的,Swagger也是支持这种解决方案

3.2 重写核心接口

在网关中新增一个供访问的前端控制器SwaggerResourceController

/**
 * @ClassName SwaggerResourceController
 * @Desc TODO   重写核心接口
 * @Date 2020/1/26 6:38 PM
 * @Version 1.0
 */
@RestController
@RequestMapping("/swagger-resources")
public class SwaggerResourceController {

    private MySwaggerResourceProvider swaggerResourceProvider;

    @Autowired
    public SwaggerResourceController(MySwaggerResourceProvider swaggerResourceProvider) {
        this.swaggerResourceProvider = swaggerResourceProvider;
    }

    @RequestMapping(value = "/configuration/security")
    public ResponseEntity<SecurityConfiguration> securityConfiguration() {
        return new ResponseEntity<>(SecurityConfigurationBuilder.builder().build(), HttpStatus.OK);
    }

    @RequestMapping(value = "/configuration/ui")
    public ResponseEntity<UiConfiguration> uiConfiguration() {
        return new ResponseEntity<>(UiConfigurationBuilder.builder().build(), HttpStatus.OK);
    }

    @RequestMapping
    public ResponseEntity<List<SwaggerResource>> swaggerResources() {
        return new ResponseEntity<>(swaggerResourceProvider.get(), HttpStatus.OK);
    }

}
  • 此时对应的正是每个服务工程访问资源信息的/swagger-resources接口地址
  • 重点就是要在swaggerResources()方法中把所有需要的服务工程的资源信息返回出来;可以看出,这个方法的返回类型里面刚好可以放入List集合

3.3 获取服务工程的资源信息

3.3.1 SwaggerResource

SwaggerResource资源信息对象,里面需要服务工程的地址和名称两个属性;在网关中,可以轻易的获取到所有工程的路由信息,所以这个时候要做的就是,遍历所有路由,把每个路由的地址和名称封装到SwaggerResource对象中,并添加到集合,最后返回出去

3.3.2 过滤

然后并不是所有的工程都需要添加到Swagger资源信息集合中,哪些需要:有接口的服务工程,如基础工程日志工程;那么其他的工程就需要过滤掉。

怎么过滤?

  1. 在需要过滤的工程的配置文件中,修改应用名称为统一格式
  application:
      # 应用名称
      name: base-service-core

---

  application:
      # 应用名称
      name: log-service-core		
  1. 在遍历添加路由的时候做判断
    /**
     * 特定服务名称后缀
     */
    public static final String SERVICE_SUFFIX = "core";

	...
	
	.filter(route -> route.getUri().getHost().indexOf(SERVICE_SUFFIX.toUpperCase()) != -1)

3.4 其它

  1. 由于网关没有引入公用工程(公用工程中配置了Swagger的依赖),所以还需要在网关中引入springfox-swagger2依赖
	<springfox.version>2.9.2</springfox.version>

	...

	<!-- swagger 依赖 -->
	<dependency>
		<groupId>io.springfox</groupId>
		<artifactId>springfox-swagger2</artifactId>
		<version>${springfox.version}</version>
	</dependency>
	<dependency>
		<groupId>io.springfox</groupId>
		<artifactId>springfox-swagger-ui</artifactId>
		<version>${springfox.version}</version>
	</dependency>
  1. 版本号的升级

4. 验证


4.1 接口

  1. 下载v1.4.2标签的代码或者对照本篇博客更改v1.4.1标签的代码
  2. 项目启动后,访问地址 http://localhost:8000/swagger-ui.html
  3. 在页面右上角Select a spec处可以切换不同工程的接口文档

5. 结语


如果是专门开发接口供他人调用,我觉得集成Swagger还是非常有必要的,如我手里正在做的一个项目,专门为客户提供他们系统的接口,还又是pc又是app,有时候同样的接口还得整理几套接口文档;而且接口不是一次能写好的,需求的变更等原因导致接口改了,那么接口文档也要更上…这是非常浪费时间的!

如果集成了Swagger,代码写好发布后,就可以直接获取到最新的接口文档了:

“代码即接口文档,接口文档即代码”,巴适。


希望能够帮助到你

over




你可能感兴趣的:(初学者商城)