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

虽然使用Swagger可以为Spring MVC编写的接口生成了API文档,但是在微服务化之后,这些API文档都离散在各个微服务中,是否有办法将这些接口都整合到一个文档中?之前给大家的回复都只是简单的说了个思路,昨天正好又有人问起,索性就举个例子写成博文供大家参考吧。

准备工作

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

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

  • 第一步:构建一个基础的Spring Boot应用,在pom.xml中引入eureka的依赖、web模块的依赖以及swagger的依赖(这里使用了我们自己构建的starter,详细可点击查看)。主要内容如下:
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.10.RELEASE</version>
    <relativePath/>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>com.spring4all</groupId>
        <artifactId>swagger-spring-boot-starter</artifactId>
        <version>1.7.0.RELEASE</version>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Dalston.SR1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
  • 第二步:编写应用主类:
@EnableSwagger2Doc
@EnableDiscoveryClient
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(true).run(args);
    }

    @RestController
    class AaaController {
        @Autowired
        DiscoveryClient discoveryClient;

        @GetMapping("/service-a")
        public String dc() {
            String services = "Services: " + discoveryClient.getServices();
            System.out.println(services);
            return services;
        }
    }
}

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

  • 第三步:设置配置文件内容
spring.application.name=swagger-service-a
server.port=10010

eureka.client.serviceUrl.defaultZone=http://localhost:1001/eureka/
swagger.base-package=com.liu

eureka.client.serviceUrl.defaultZone指定了eureka注册中心的地址
swagger.base-package参数制定了要生成文档的package,只有com.liu包下的Controller才会被生成文档。

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

构建API网关并整合Swagger

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

  • 第一步:在pom.xml中引入swagger的依赖,这里同样使用了我们自制的starter,所以主要的依赖包含下面这些:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
    <groupId>com.spring4all</groupId>
    <artifactId>swagger-spring-boot-starter</artifactId>
    <version>1.7.0.RELEASE</version>
</dependency>
  • 第二步:在应用主类中配置swagger,具体如下:
@EnableSwagger2Doc
@EnableZuulProxy
@SpringCloudApplication
public class Application {

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(true).run(args);
    }

    @Component
    @Primary
    class DocumentationConfig implements SwaggerResourcesProvider {
        @Override
        public List<SwaggerResource> get() {
            List resources = new ArrayList<>();
            resources.add(swaggerResource("service-a", "/swagger-service-a/v2/api-docs", "2.0"));
            resources.add(swaggerResource("service-b", "/swagger-service-b/v2/api-docs", "2.0"));
            return resources;
        }
     //定义swaggerResource的构造函数
        private SwaggerResource swaggerResource(String name, String location, String version) {
            SwaggerResource swaggerResource = new SwaggerResource();
            swaggerResource.setName(name);
            swaggerResource.setLocation(location);
            swaggerResource.setSwaggerVersion(version);
            return swaggerResource;
        }
    }
}

代码讲解:@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文档,从而实现汇总加载内容。(解释:当然了我们可以直接在浏览器地址栏输入该地址即可访问该文档,但是在这里我们使用了zuul网关,也就是说我们只需要访问Zuul所在的网关服务即可,然后由该网关来帮我们做路由访问转发到各个服务器上,Zuul网关可以看成是一个门户应用,帮我们把各个服务器的swagger文档做汇总,我们直接到这个门户应用上就可以看到各个服务器的swagger生成的文档

测试验证

将上面构建的两个微服务以及API网关都启动起来之后,访问网关的swagger页面,
注意:swagger-api-gateway应用的application.properties文件配置如下

spring:
  application:
    name: swagger-api-gateway

server:
  port: 11000
  eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:1001/eureka/

比如:http://localhost:11000/swagger-ui.html,(这里的swagger-api-gateway应用(也就是所谓的“门户”)的server.port=11000,)此时可以看到如下图所示的内容:
在这里插入图片描述
可以看到在分组选择中就是当前配置的两个服务的选项,选择对应的服务名之后就会展示该服务的API文档内容。(看,这个zuul门户的作用多牛逼,想看service-a或service-b中的哪个就看哪个) 当然了我们也可以不通过zuul门户来访问service-a或service-b的swagger文档,而是直接访问service-a或service-b应用的地址所来得到,举例如下:
直接在浏览器输入service-a应用的访问swagger文档的url即可。(这里service-a的server.port=10010)
在这里插入图片描述
本文转载自http://blog.didispace.com/Spring-Cloud-Zuul-use-Swagger-API-doc/

posted @ 2019-07-10 13:35  抬头不见星空  阅读(79)  评论(0)    收藏  举报