美文网首页
Swagger2源码-如何动态生成接口文档

Swagger2源码-如何动态生成接口文档

作者: pq217 | 来源:发表于2022-08-10 08:24 被阅读0次

前言

之前有朋友问到怎么动态生成swagger2的文档,因为大部分swagger2的使用是给controller代码加入@API注解,自动生成的文档,但如果在没有controller的情况下如何生成一个接口文档?

比如上文五步搭建自己的低代码平台搭建的低代码平台,接口都是自动生成,没有controller代码的,那么如何生成这种动态接口对应的swagger2接口文档

本文还是只提供思路,捎带swagger2的源码讲解,毕竟只要懂swagger2的运行原理,想凭空加入接口文档,实属轻而易举

SwaggerResource

直译为"Swagger的资源",Swagger文档是区分资源的,每个资源有自己的名字(name)、地址(url)、版本(swaggerVersion)

SwaggerResource

这个资源的区分如何体现的呐?打开swagger2的前端界面

swagger-ui.html doc.html

每一个选项即代表一个资源(写过gateway集成接口文档的应该很眼熟),进入前端界面第二个请求的数据就是可选项

swagger-resources

如果是自动生成的接口文档,那么只有一个默认SwaggerResource,名字为“default”,url为/v2/api-docs

url

名字(name),版本(version)都挺好理解,这个url是什么意思呐?

答:是一个springweb的访问路径,每个资源有一个访问路径,而请求该路径的返回结果就是这个资源的配置,当我们前端选中某个资源时,就会对路径发起请求去获取该资源的配置(进入界面默认自动访问第一个资源的路径)

api-docs

那么就有疑问了,这个访问路径可以获取配置数据,也就是一个接口,那么这个接口是谁写的呐?

自动生成文档情况下,这个接口是Swagger内部帮我们实现的,默认访问路径是/v2/api-docs

源码在springfox.documentation.swagger2.web.Swagger2Controller,源码截取重点如下

@Controller
@ApiIgnore
public class Swagger2Controller {

  public static final String DEFAULT_URL = "/v2/api-docs";

  @RequestMapping(
      value = DEFAULT_URL,
      method = RequestMethod.GET,
      produces = { APPLICATION_JSON_VALUE, HAL_MEDIA_TYPE })
  @ResponseBody
  public ResponseEntity<Json> getDocumentation(
      @RequestParam(value = "group", required = false) String swaggerGroup,
      HttpServletRequest servletRequest) {

    String groupName = Optional.fromNullable(swaggerGroup).or(Docket.DEFAULT_GROUP_NAME);
    // 获取扫描注解获取的接口配置信息
    Documentation documentation = documentationCache.documentationByGroup(groupName);
    // 返回的实体
    Swagger swagger = mapper.mapDocumentation(documentation);
    return new ResponseEntity<Json>(jsonSerializer.toJson(swagger), HttpStatus.OK);
  }

swagger通过扫描注解等方式自动生成default资源的信息,包括资源名称,版本等基础信息,和所有接口的配置信息,封装成Swagger对象返回给前端,前端根据这个对象信息就画出整个文档界面

Swagger对象

Swagger对象封装的信息就是文档某资源的所有信息,看一下它的重点参数

Swagger
basePath

基础路径,一般是"/", 如果通过网关访问则是"/{predicates}"

info

文档名称,版本,描述等

host

ip+端口

tags

文档目录

definitions

所有实体Model的定义,包含Model的类型,属性等,在下图可查看

Models
paths&parameters&responses

这几个最重要的,即所有接口配置的集合,接口的配置包括路径,参数,返回等信息

扩展

以上Swagger2源码示意图如下

Swagger2

研究完Swagger2机制,现在回到问题本身,如何动态生成文档(在没有controller代码情况下),以下提供两个思路

思路1

重写Swagger2Controller,再Swagger对象返回前修改,加入新的接口信息,应该可行,但我没试过

思路2

提供一个新的SwaggerResource,url指向自己写的接口,想返回什么就自己随意写了,只要符合他的返回数据规范即可,重点介绍一下这个方法

SwaggerResourcesProvider接口即SwaggerResource的提供者,它的默认实现注入到了Spring容器中

SwaggerResourcesProvider

这就是一个扫描注解提供default资源的实现,我们可以在加一个SwaggerResourcesProvider的实现,并注入Spring容器,并使用@Primary注解让其被优先使用

@Bean
@Primary
public SwaggerResourcesProvider customSwaggerResourcesProvider() throws NoSuchMethodException {
    return () -> {
        List<SwaggerResource> resources = new ArrayList<>();
        // 添加自定义文档资源
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName("custom");
        swaggerResource.setLocation("自定义接口地址...");
        swaggerResource.setSwaggerVersion("2.0");
        resources.add(swaggerResource);

        Map<String, SwaggerResourcesProvider> beans = applicationContext.getBeansOfType(SwaggerResourcesProvider.class);
        // 获取default文档资源信息,并加回
        for (Map.Entry<String, SwaggerResourcesProvider> entry : beans.entrySet()) {
            if (!"customSwaggerResourcesProvider".equalsIgnoreCase(entry.getKey())) {
                List<SwaggerResource> defaultSwaggerResources = entry.getValue().get();
                resources.addAll(defaultSwaggerResources);
            }
        }
        return resources;
    };
}

写一个Rest接口返回动态的接口文档配置信息,其访问路径与在setLocation指向的路径对应即可

至于这个接口的写法,爱怎写都行(可以读数据库,可以读文件),只要返回数据符合他的规则即可(否则前端报错)

dynamic-api

相关文章

网友评论

      本文标题:Swagger2源码-如何动态生成接口文档

      本文链接:https://www.haomeiwen.com/subject/bmwnwrtx.html