【Swagger】动态多源的SwaggerAPI文档生成

背景

新需求中需要实现动态生成API及文档的功能,生成API不说,但动态生成Restful风格的API一般没接触过,以往都是直接代码扫描产生文档的,这次需要进行研究

设计思想

首先在熟悉完整个OpenAPI设计规范及Swagger-UI后,设计起来没那么困难了,主要需要抓住两个关键点:

  • 开源的Swagger-UI项目,是可以传入不同的json/yaml来展现不同的API文档的,这个网上挺多的,不展开
  • 实现动态文档,就需要依托数据库进行存取,合理的拆解Swagger结构并存储会将问题简单化,例如将单独的json结构存放在MongoDB中

具体设计

主要POM

由于项目使用Spring Boot,所以主要有springfox-swagger2及swagger官方包组成

<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger-ui</artifactId>
			<version>2.8.0</version>
			<scope>compile</scope>
		</dependency>
			<dependency>
				<groupId>io.springfox</groupId>
				<artifactId>springfox-swagger2</artifactId>
				<version>2.8.0</version>
				<scope>compile</scope>
			</dependency>
		<!-- https://mvnrepository.com/artifact/io.swagger/swagger-core -->
		<dependency>
			<groupId>io.swagger</groupId>
			<artifactId>swagger-core</artifactId>
			<version>1.6.0</version>
		</dependency>
		<dependency>
			<groupId>io.swagger</groupId>
			<artifactId>swagger-models</artifactId>
			<version>1.6.0</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.62</version>
		</dependency>

模型设计

这个其实在swagger-models包已经做好定义了,我们要做的只是new一个并使用,当然直接使用json也不是不可以,这里将Swagger拆分为(真正只有json字段部分有效):

  • 主体:
{
   "id": "aaa",
   "name": "代码生成json",
   "json": {
	   "swagger": "2.0",
	   "info": {
			"contact": {
				"name": "Wilson Support",
				"url": "http://www.baidu.com",
				"email": "support@wilson.com"
		   },
			"description": "代码生成json",
			"title": "我的Swagger REST API",
			"version": "0.0.1"
		},
		"basePath": "/v1",
		"host": "127.0.0.1:8080",
		"schemes": ["http"]
	}
}
  • 标签:
{
   "id": "1",
   "swaggerId": "aaa",
   "json": {"name": "tag1", "description": "test"}
}
  • 具体API:
{
   "id": "1",
   "swaggerId": "aaa",
   "json": {
	   "/users": {
		   "get": {
			   "summary": "查询用户",
			   "tags": ["tag1"],
			   "produces": ["application/json"],
		   "consumes": ["application/json],
			   "description": "。。。。。",
			   "responses": {
				   "200": {"description": "Success"},
				   "400": {"description": "Bad request"},
				   "401": {"description": "Unauthorized"},
				   "500": {"description": "Internal Server Error"},
				   "403": {"description": "Forbidden"},
				   "404": {"description": "Not found"}
			   },
			   "parameters": [{
				   "in": "query",
				   "name": "userName",
				   "description": "用户名称",
				   "type": "string",
				   "required": true
			   }]
		  }
	   }
  }
}
  • 模型描述:
{
   "id": "1",
   "swaggerId": "aaa",
   "name": "返回结果",
   "json": {
	   "resultDto": {
		   "properties": {
			   "msg": {
				   "default": "成功",
				   "type": "string"
			  },
			   "code": {
				   "default": "000000",
				   "type": "string"
			  },
			   "data": {
				   "type": "object"
			  }
		  }
	   }
  }
}

拼接设计

拼接Swagger=主体+n标签+nAPI+n*模型,用swaggerId外键字段来匹配相应部分,这样,可以动态新增非主体部分

多源展示代码

demo使用的是springfox的ui,其实只是利用了springfox的SwaggerResourcesProvider,它能指定API文档的来源(你也可以直接用swagger-ui前端项目),下面是代码

/**
 * Swagger多源配置
 * <li>目标:保证启动后swagger-ui.html能展示来自不同类型的文档</li>
 * <li>使用方式:配置后自动生效,一定要配置允许跨域</li>
 * <li>现有bug:无</li>
 * @author Wilson 2020/02/06
 * @version 0.0.1
 * @since 0.0.1
 * @see SwaggerResource
 */
@Configuration
@EnableSwagger2
public class SwaggerConfig extends WebMvcConfigurationSupport {

    /**
     * Swagger多源,体现在swagger-ui可列表选择不同swagger文档
     * @param defaultResourcesProvider
     * @return swagger资源生产者
     */
    @Bean
    @Primary
    public SwaggerResourcesProvider swaggerResourcesProvider(InMemorySwaggerResourcesProvider defaultResourcesProvider) {
        return () -> {
            List<SwaggerResource> resourcesList = new ArrayList<>();

            // 静态文件,存于resources文件夹下
            SwaggerResource resource1 = new SwaggerResource();
            resource1.setName("静态YML");
            resource1.setSwaggerVersion("2.0");
            resource1.setLocation("/swagger-api.yml");
            resourcesList.add(resource1);

            // 模拟数据库获取拼接的文档,请求见SwaggerController
            SwaggerResource resource2 = new SwaggerResource();
            resource2.setName("动态API");
            resource2.setSwaggerVersion("2.0");
            resource2.setLocation("/json");
            resourcesList.add(resource2);

            // 自身代码扫描生成的文档,默认路径http://localhost:8080/v2/api-docs
            SwaggerResource resource3 = new SwaggerResource();
            resource3.setName("自身");
            resource3.setSwaggerVersion("2.0");
            resource3.setLocation("/v2/api-docs");
            resourcesList.add(resource3);
            return resourcesList;
        };
    }

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.wilson.demo.swagger.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("springboot利用swagger构建api文档")
                .description("简单优雅的restful风格")
                .version("0.1")
                .build();
    }

    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("/","classpath:/");
    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
                .maxAge(3600)
                .allowCredentials(true);
    }
}

代码Demo

参考资料

OpenAPI规范

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值