Swagger2API接口管理

1.课题引入

随着微服务架构体系的发展和应用, 为了前后端能够更好的集成与对接,同时为了项目的方便交付,每个项目都需要提供相应的API文档。

来源:PC端、微信端、H5端、移动端(安卓和IOS端)

2.传统的API文档编写存在以下几个痛点

对API文档进行更新的时候,需要通知前端开发人员,导致文档更新交流不及时;

API接口返回信息不明确

大公司中肯定会有专门文档服务器对接口文档进行更新。

缺乏在线接口测试,通常需要使用相应的API测试工具,比如postman、SoapUI等

接口文档太多,不便于管理

为了解决传统API接口文档维护的问题,为了方便进行测试后台Restful接口并实现动态的更新,因而引入Swagger接口工具。

3.Swagger具有以下优点

1.功能丰富:支持多种注解,自动生成接口文档界面,支持在界面测试API接口功能;

2.及时更新:开发过程中花一点写注释的时间,就可以及时的更新API文档,省心省力;

3.整合简单:通过添加pom依赖和简单配置,内嵌于应用中就可同时发布API接口文档界面,不需要部署独立服务。

4.Swagger 2.0 集成配置

4.1.Maven依赖信息

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.1.RELEASE</version>
	</parent>
	<!-- 管理依赖 -->
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Finchley.M7</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	<dependencies>
		<!-- SpringBoot整合Web组件 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- SpringBoot整合eureka客户端 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>
		<!-- swagger2 -->
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger2</artifactId>
			<version>2.8.0</version>
		</dependency>
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger-ui</artifactId>
			<version>2.8.0</version>
		</dependency>
	</dependencies>
	<!-- 注意: 这里必须要添加, 否者各种依赖有问题 -->
	<repositories>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/libs-milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>

4.2.SwaggerConfig

@Configuration
@EnableSwagger2
public class SwaggerConfig {

	@Bean
	public Docket createRestApi() {
		return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
				// api扫包
				.apis(RequestHandlerSelectors.basePackage("com.itmayiedu.api")).paths(PathSelectors.any()).build();
	}

	private ApiInfo apiInfo() {
		return new ApiInfoBuilder().title("每特教育|蚂蚁课堂 微服务电商系统").description("每特教育|蚂蚁课堂 Java分布式&微服务培训")
				.termsOfServiceUrl("http://www.itmayiedu.com")
				// .contact(contact)
				.version("1.0").build();
	}

}

Swagger模板

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>swagger-bootstrap-ui</artifactId>
    <version>1.9.0</version>
</dependency>
<dependency>
    <groupId>io.swagger</groupId>
    <artifactId>swagger-models</artifactId>
    <version>1.5.21</version>
</dependency>
//@Profile({ "dev", "test" }) 指定环境
@Configuration
@EnableSwagger2
//在1.9.0版本或之后版本,SwaggerBootstrapUi提供了简单的Basic认证功能
//@EnableSwaggerBootstrapUI 账户权限配置
public class SwaggerConfig {

	@Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                // api扫包
                .apis(RequestHandlerSelectors.basePackage("com.xxx.controller"))
                // 接口地址前缀
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("xxxx系统")
                .description("xxxxxx描述")
                .termsOfServiceUrl("http://www.xxxxx.com")
                .contact(new Contact("karma", null, null))
                .version("1.0")
                .build();
    }

}

若添加了账户权限配置,在yml文件添加一下配置

swagger:
  production: false
  basic:
    enable: true
    username: admin
    password: admin

访问-> ip:端口/前缀/swagger-ui.html 或者 ip:端口/前缀/doc.html

/doc.html    SwaggerBootstrapUi提供的文档访问地址
/api-docs-ext    SwaggerBootstrapUi提供的增强接口地址
/swagger-resources    Springfox-Swagger提供的分组接口
/api-docs    Springfox-Swagger提供的分组实例详情接口
/swagger-ui.html    Springfox-Swagger提供的文档访问地址
/swagger-resources/configuration/ui    Springfox-Swagger提供
/swagger-resources/configuration/security    Springfox-Swagger提供

5.Zull整合Swagger管理微服务所有API

5.1.会员和订单

5.1.1.引入Maven依赖
<!-- swagger-spring-boot -->
<dependency>
	<groupId>com.spring4all</groupId>
	<artifactId>swagger-spring-boot-starter</artifactId>
	<version>1.7.0.RELEASE</version>
</dependency>
5.1.2.application.yml配置

Api接口扫描范围

swagger:
  base-package: com.wmh.wechat.service
  title: 微信服务系统
  description: 微信服务接口
  version: 1.1
  terms-of-service-url: http://127.0.0.1:9090
  contact:
    name: karma
    email: xxxxxx@qq.com
    url: http://127.0.0.1:9090
  enabled: true
5.1.3.项目启动引入开启生成文档

@EnableSwagger2Doc

5.2.ZuulGateway网关

@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
@EnableSwagger2Doc
public class AppGateWay {

	// @EnableZuulProxy 开启网关代理

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

	// zuul配置能够使用config实现实时更新
	@RefreshScope
	@ConfigurationProperties("zuul")
	public ZuulProperties zuulProperties() {
		return new ZuulProperties();
	}

	// 添加文档来源
	@Component
	@Primary
	class DocumentationConfig implements SwaggerResourcesProvider {
		@Override
		public List<SwaggerResource> get() {
			List resources = new ArrayList<>();
			// app-itmayiedu-order
			resources.add(swaggerResource("app-itmayiedu-member", "/api-member/v2/api-docs", "2.0"));
			resources.add(swaggerResource("app-itmayiedu-order", "/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;
		}
	}
}

Maven依赖信息

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

5.3.Swagger整合Gateway网关

5.3.1 添加maven依赖
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
</dependencies>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>swagger-bootstrap-ui</artifactId>
    <version>1.9.0</version>
</dependency>
<dependency>
    <groupId>io.swagger</groupId>
    <artifactId>swagger-models</artifactId>
    <version>1.5.21</version>
</dependency>
5.3.2 添加获取swagger /v2/api-docs接口信息配置类
@Component
@Primary
@AllArgsConstructor
public class SwaggerProvider implements SwaggerResourcesProvider {
    public static final String API_URI = "/v2/api-docs";
    private final RouteLocator routeLocator;
    private final GatewayProperties gatewayProperties;


    @Override
    public List<SwaggerResource> get() {
        List<SwaggerResource> resources = new ArrayList<>();
        List<String> routes = new ArrayList<>();
        routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
        gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId()))
                .forEach(routeDefinition -> routeDefinition.getPredicates().stream()
                        .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
                        .forEach(predicateDefinition -> resources.add(swaggerResource(routeDefinition.getId(),
                                predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
                                        .replace("/**", API_URI)))));
        return resources;
    }

    private SwaggerResource swaggerResource(String name, String location) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        swaggerResource.setSwaggerVersion("2.0");
        return swaggerResource;
    }
}
5.3.3 添加swagger地址过滤器
@Component
@Deprecated
public class SwaggerHeaderFilter extends AbstractGatewayFilterFactory {
    private static final String HEADER_NAME = "X-Forwarded-Prefix";

    @Override
    public GatewayFilter apply(Object config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            String path = request.getURI().getPath();
            if (!StringUtils.endsWithIgnoreCase(path, SwaggerProvider.API_URI)) {
                return chain.filter(exchange);
            }

            String basePath = path.substring(0, path.lastIndexOf(SwaggerProvider.API_URI));


            ServerHttpRequest newRequest = request.mutate().header(HEADER_NAME, basePath).build();
            ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
            return chain.filter(newExchange);
        };
    }
}
5.3.4 添加swagger适配器
/**
 * SwaggerHandler
 */
@RestController
@RequestMapping("/swagger-resources")
public class SwaggerHandler {
    @Autowired(required = false)
    private SecurityConfiguration securityConfiguration;
    @Autowired(required = false)
    private UiConfiguration uiConfiguration;
    private final SwaggerResourcesProvider swaggerResources;

    @Autowired
    public SwaggerHandler(SwaggerResourcesProvider swaggerResources) {
        this.swaggerResources = swaggerResources;
    }


    @GetMapping("/configuration/security")
    public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
        return Mono.just(new ResponseEntity<>(
                Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
    }

    @GetMapping("/configuration/ui")
    public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {
        return Mono.just(new ResponseEntity<>(
                Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
    }

    @GetMapping("")
    public Mono<ResponseEntity> swaggerResources() {
        return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
    }
}
5.3.5 添加application.yml文件
server:
  port: 80
spring:
  application:
    name: wmh-gateway
  cloud:
    nacos:
      discovery:
        ##nacos服务注册地址
        server-addr: 127.0.0.1:8848
    gateway:
      locator:
        enabled: true
      routes:
        - id: wmh-wechat
          uri: lb://wmh-wechat
          predicates:
            - Path=/wmh-wechat/**
          filters:
            - SwaggerHeaderFilter
            - StripPrefix=1
        - id: wmh-member
          uri: lb://wmh-member
          predicates:
            - Path=/wmh-member/**
          filters:
            - SwaggerHeaderFilter
            - StripPrefix=1

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

Kafka集群设计原理 上一篇
Gradle 入门教程 下一篇