查看原文
其他

Spring Cloud Zuul中使用Swagger汇总API接口文档

翟永超 程序猿DD 2019-07-13

有很多读者问过这样的一个问题:


虽然使用Swagger可以为Spring MVC编写的接口生成了API文档,但是在微服务化之后,这些API文档都离散在各个微服务中,是否有办法将这些接口都整合到一个文档中?


之前给大家的回复都只是简单的说了个思路,昨天正好又有人问起,索性就举个例子写成博文供大家参考吧。


如果你还不了解 SpringCloudZuul和 Swagger,建议优先阅读下面两篇,有一个初步的了解:

1、准备工作

上面说了问题的场景是在微服务化之后,所以我们需要先构建两个简单的基于Spring Cloud的微服务,命名为 swagger-service-a和 swagger-service-b

下面只详细描述一个服务的构建内容,另外一个只是名称不同,如有疑问可以在文末查看详细的代码样例。

  • 第一步:构建一个基础的Spring Boot应用,在 pom.xml中引入eureka的依赖、web模块的依赖以及swagger的依赖(这里使用了我们自己构建的starter,详细可点击查看)。


    主要内容如下:

  1. <parent>

  2.    <groupId>org.springframework.boot</groupId>

  3.    <artifactId>spring-boot-starter-parent</artifactId>

  4.    <version>1.5.10.RELEASE</version>

  5.    <relativePath/>

  6. </parent>

  7. <dependencies>

  8.    <dependency>

  9.        <groupId>org.springframework.cloud</groupId>

  10.        <artifactId>spring-cloud-starter-eureka</artifactId>

  11.    </dependency>

  12.    <dependency>

  13.        <groupId>org.springframework.boot</groupId>

  14.        <artifactId>spring-boot-starter-web</artifactId>

  15.    </dependency>

  16.    <dependency>

  17.        <groupId>com.spring4all</groupId>

  18.        <artifactId>swagger-spring-boot-starter</artifactId>

  19.        <version>1.7.0.RELEASE</version>

  20.    </dependency>

  21. </dependencies>

  22. <dependencyManagement>

  23.    <dependencies>

  24.        <dependency>

  25.            <groupId>org.springframework.cloud</groupId>

  26.            <artifactId>spring-cloud-dependencies</artifactId>

  27.            <version>Dalston.SR1</version>

  28.            <type>pom</type>

  29.            <scope>import</scope>

  30.        </dependency>

  31.    </dependencies>

  32. </dependencyManagement>


  • 第二步:编写应用主类:


  1. @EnableSwagger2Doc

  2. @EnableDiscoveryClient

  3. @SpringBootApplication

  4. public class Application {

  5.    public static void main(String[] args) {

  6.        new SpringApplicationBuilder(Application.class).web(true).run(args);

  7.    }

  8.    @RestController

  9.    class AaaController {

  10.        @Autowired

  11.        DiscoveryClient discoveryClient;

  12.        @GetMapping("/service-a")

  13.        public String dc() {

  14.            String services = "Services: " + discoveryClient.getServices();

  15.            System.out.println(services);

  16.            return services;

  17.        }

  18.    }

  19. }


其中, @EnableSwagger2Doc注解是我们自制Swagger Starter中提供的自定义注解,通过该注解会初始化默认的Swagger文档设置。下面还创建了一个通过Spring MVC编写的HTTP接口,用来后续在文档中查看使用。

  • 第三步:设置配置文件内容:


  1. spring.application.name=swagger-service-a

  2. server.port=10010

  3. eureka.client.serviceUrl.defaultZone=http://eureka.didispace.com/eureka/

  4. swagger.base-package=com.didispace


其中,eureka服务端的配置采用了本站的公益eureka,大家可以通过http://eureka.didispace.com/查看详细以及使用方法。另外, swagger.base-package参数制定了要生成文档的package,只有 com.didispace包下的Controller才会被生成文档。

注意:上面构建了swagger-service-a服务,swagger-service-b服务可以如法炮制,不再赘述。

2、构建API网关并整合Swagger

Spring Cloud构建微服务架构:服务网关(基础)一文中,已经非常详细的介绍过使用Spring Cloud Zuul构建网关的详细步骤,这里主要介绍在基础网关之后,如何整合Swagger来汇总这些API文档。

  • 第一步:在 pom.xml中引入swagger的依赖,这里同样使用了我们自制的starter,所以主要的依赖包含下面这些:


  1. <dependency>

  2.    <groupId>org.springframework.cloud</groupId>

  3.    <artifactId>spring-cloud-starter-zuul</artifactId>

  4. </dependency>

  5. <dependency>

  6.    <groupId>org.springframework.cloud</groupId>

  7.    <artifactId>spring-cloud-starter-eureka</artifactId>

  8. </dependency>

  9. <dependency>

  10.    <groupId>com.spring4all</groupId>

  11.    <artifactId>swagger-spring-boot-starter</artifactId>

  12.    <version>1.7.0.RELEASE</version>

  13. </dependency>


  • 第二步:在应用主类中配置swagger,具体如下:


  1. @EnableSwagger2Doc

  2. @EnableZuulProxy

  3. @SpringCloudApplication

  4. public class Application {

  5.    public static void main(String[] args) {

  6.        new SpringApplicationBuilder(Application.class).web(true).run(args);

  7.    }

  8.    @Component

  9.    @Primary

  10.    class DocumentationConfig implements SwaggerResourcesProvider {

  11.        @Override

  12.        public List<SwaggerResource> get() {

  13.            List resources = new ArrayList<>();

  14.            resources.add(swaggerResource("service-a", "/swagger-service-a/v2/api-docs", "2.0"));

  15.            resources.add(swaggerResource("service-b", "/swagger-service-b/v2/api-docs", "2.0"));

  16.            return resources;

  17.        }

  18.        private SwaggerResource swaggerResource(String name, String location, String version) {

  19.            SwaggerResource swaggerResource = new SwaggerResource();

  20.            swaggerResource.setName(name);

  21.            swaggerResource.setLocation(location);

  22.            swaggerResource.setSwaggerVersion(version);

  23.            return swaggerResource;

  24.        }

  25.    }

  26. }


说明: @EnableSwagger2Doc上面说过是开启Swagger功能的注解。这里的核心是下面对 SwaggerResourcesProvider的接口实现部分,通过 SwaggerResource添加了多个文档来源,按上面的配置,网关上Swagger会通过访问 /swagger-service-a/v2/api-docs和 swagger-service-b/v2/api-docs来加载两个文档内容,同时由于当前应用是Zuul构建的API网关,这两个请求会被转发到 swagger-service-a和 swagger-service-b服务上的 /v2/api-docs接口获得到Swagger的JSON文档,从而实现汇总加载内容。

3、测试验证

将上面构建的两个微服务以及API网关都启动起来之后,访问网关的swagger页面,比如: http://localhost:11000/swagger-ui.html,此时可以看到如下图所示的内容:


可以看到在分组选择中就是当前配置的两个服务的选项,选择对应的服务名之后就会展示该服务的API文档内容。

5、代码示例

本文示例读者可以通过查看下面仓库的中的 swagger-service-a、 swagger-service-b、 swagger-api-gateway三个项目:

  • Github:

    https://github.com/dyc87112/SpringCloud-Learning/tree/master/2-Dalston%E7%89%88%E6%95%99%E7%A8%8B%E7%A4%BA%E4%BE%8B/

  • Gitee:

    https://gitee.com/didispace/SpringCloud-Learning/tree/master/2-Dalston%E7%89%88%E6%95%99%E7%A8%8B%E7%A4%BA%E4%BE%8B


除了本文的方法之外,我还开发了一个开源项目,您也可以直接来使用,欢迎Star支持:https://github.com/dyc87112/swagger-butler


最后再给大家推荐一个《零基础学Python》的视频课程。


Python这门编程,我是非常推荐大家要去掌握的,由于该课程属于基础类课程,所以一些非计算机专业的朋友也可以去尝试学习和应用。因为它比起Java来说它更容易上手,通过一些基础知识内容就可以帮助减轻一些日常工作繁琐的事情,让你能够事半功倍。加上现在爬虫、AI等框架的发展,如果你有足够的积极性和想象空间,可以玩的内容会越来越多,所以我把这个专栏推荐给你,希望你可以喜欢并有所收获!



- END -


 往期推荐:

  • 死磕Java系列:

死磕Java并发:深入分析ThreadLocal

死磕Java并发:深入分析synchronized的实现原理

……


  • Spring系列:

Spring Cloud Config Server迁移节点或容器化带来的问题

Spring Cloud Config对特殊字符加密的处理

Spring Boot使用@Async实现异步调用:使用Future以及定义超时

Spring Cloud构建微服务架构:分布式配置中心(加密解密)

Spring Boot快速开发利器:Spring Boot CLI

……

可关注我的公众号

深入交流、更多福利

扫码加入我的知识星球


点击“阅读原文”,看本号其他精彩内容

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存