前言:

  1. 在微服务架构中,除了与前端联调之外,我们各个服务之间也存在着调用接口的情况,这时候就需要提供一份API (接口文档),提供给其他调用你的服务的人使用。而往往我们接口更新后,而没来得及更新文档或忘记更新文档,这时候就造成接口与接口文档不一致的问题,人家按旧的接口文档调用你的服务,导致无法正确调用接口,这时候我们可以使用Swagger来帮我们动态生成API文档,还支持网页中直接测试调用接口。

  2. 在微服务项目中,每个项目都有一个对应的API文档,非常不便于管理,我们可以在每个微服务中使用一下配置,将SwaggerUI的地址绑定到Eureka注册中心对应服务的Status的ip上,我们访问Eureka,点击IP就可以直接访问对应的Swagger了。

    eureka:
        instance:
            status-page-url: http:// s p r i n g . c l o u d . c l i e n t . i p − a d d r e s s : {spring.cloud.client.ip-address}: spring.cloud.client.ipaddress:{server.port}/swagger-ui.html

  3. 虽然上面的方式也可以做到帮我们统一管理微服务接口文档,但是显得繁琐,因此我们将使用Zull网关实现统一管理所有微服务的接口文档。

一、准备工作

要求:搭建前,应该对Eureka、Zuul和使用Swagger应该都有一定的了解。

1. 创建Eureka服务(略)
2. 创建会员服务
  • 添加Swagger依赖,其他依赖不一 一罗列
<!-- swagger-spring-boot -->
<dependency>
     <groupId>com.spring4all</groupId>
     <artifactId>swagger-spring-boot-starter</artifactId>
     <version>1.7.0.RELEASE</version>
 </dependency>
  • 配置文件:
#会员服务
server:
  port: 8082
spring:
  application:
    name: member-service    #服务名

#Eureka配置
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka/     #注册中心的地址
      
#Swagger配置
swagger:
  #Swagger生成文档扫描包的范围
  base-package: com.example.member
  • 启动类:
package com.example.member;

@EnableSwagger2Doc  //开启Swagger
@EnableDiscoveryClient  //发现服务
@SpringBootApplication
public class MemberApplication {

    public static void main(String[] args) {
        SpringApplication.run(MemberApplication.class, args);
    }
}
  • 创建一个接口
package com.example.member.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Api("会员控制器")   //添加了此注解的才会生成API文档
public class MemberController {

    @ApiOperation("获取会员信息")   //接口描述
    @GetMapping("/getMember")
    public String getMember(String name){
        System.out.println("调用/getMember接口!!!");
        return "getMember: "+name;
    }
}
3. 创建订单服务
  • 添加Swagger依赖,其他依赖不一 一罗列
<!-- swagger-spring-boot -->
<dependency>
     <groupId>com.spring4all</groupId>
     <artifactId>swagger-spring-boot-starter</artifactId>
     <version>1.7.0.RELEASE</version>
 </dependency>
  • 配置文件
#订单服务
server:
  port: 8081
spring:
  application:
    name: order-service   #服务名

#Eureka配置
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka/      #注册中心地址
      
#Swagger配置
swagger:
  #Swagger生成文档扫描包的范围
  base-package: com.example.order
  • 启动类
package com.example.order;

@EnableSwagger2Doc  //开启Swagger
@EnableDiscoveryClient //发现服务
@SpringBootApplication
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}

  • 创建一个接口
package com.example.order.controller;

@RestController
@Api("订单控制器")   //添加了此注解的才会生成API文档
public class OrderController {

    @ApiOperation("获取订单信息")  //接口描述
    @GetMapping("/getOrder")
    public String getOrder(String orderNo){
        return "getOrder: "+orderNo;
    }

4. 创建Zuul网关服务
  • 添加依赖
<dependencies>
       <!-- Eureka client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        
        <!-- zuul Gateway -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>

        <!-- swagger-spring-boot -->
        <dependency>
            <groupId>com.spring4all</groupId>
            <artifactId>swagger-spring-boot-starter</artifactId>
            <version>1.7.0.RELEASE</version>
        </dependency>
    </dependencies>
  • 配置文件
#网关服务
server:
  port: 82
spring:
  application:
    name: zull-gateway-service
    
#Eureka配置
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka/
  instance:
    #写定IP
    instance-id: ${spring.cloud.client.ip-address}:${server.port}
    prefer-ip-address: true
    #点击展示swaggerui
    status-page-url: http://${spring.cloud.client.ip-address}:${server.port}/swagger-ui.html
    
# 配置网关反向代理,例如访问/api-member/** 直接重定向到member-service服务,实现路由转发,隐藏服务的真实ip(服务都实在内网中)
#zull根据服务名,去Eureka获取服务真实地址,并通过本地转发,而且默认开启Ribbon实现负载均衡
#默认读取Eureka注册列表 默认30秒间隔  
zuul:
 routes:
   api-a: #会员服务网关配置
     path: /api-member/**   #访问只要是/api-member/ 开头的直接转发到member-service服务
     #服务名
     serviceId: member-service
   api-b: #订单服务网关配置
     path: /api-order/**
     serviceId: order-service
  • 启动类
package com.example.zuul;

import com.spring4all.swagger.EnableSwagger2Doc;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

import java.util.ArrayList;
import java.util.List;

@EnableSwagger2Doc//开启Swagger文档生成
@EnableDiscoveryClient
@EnableZuulProxy //开启zuul网关代理
@SpringBootApplication
@RefreshScope  // 使用该注解的类,会在接到SpringCloud配置中心配置刷新的时候自动刷新
@RestController
public class ZuulApplication {

    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication.class, args);
    }

	//这里用内部类的方式配置,也可以单独创建一个配置类文件
    @Component   
    @Primary
    class DocumentationConfig implements SwaggerResourcesProvider {
        @Override
        public List<SwaggerResource> get() {
            List resources = new ArrayList<>();
            // member-service :自定义      
            // /api-member/v2/api-docs:固定 ,其中/=/api-member是网关配置中的path
            resources.add(swaggerResource("member-service", "/api-member/v2/api-docs", "2.0"));    //会员服务
            resources.add(swaggerResource("order-service", "/api-order/v2/api-docs", "2.0"));   //订单服务
            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;
        }
    }

}

二、测试

启动所有服务,浏览器访问127.0.0.1:8761
在这里插入图片描述
点击IP进入Swagger界面
在这里插入图片描述
注:若遇不能访问到API界面,请求检查访问的服务是否开启,还有网关是否设置过滤器



------------------------------------------------------ 学习不易,需要坚持,若有不对之处望多多指点 ----------------------------------------

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐