引言

在软件开发过程中,接口设计与接口文档编写是重要的一环,特别是在前后端分离的情况下,接口说明文档是开发人员之间的连接点。接口文档的编写有很多方式,可以使用 word,但是如果接口变化,需要额外修改文档,增加工作量。如何提高写接口文档效率,在 SpringBoot 开发中,结合 Swagger 来提供接口文档说明是一个很好的实践,通过配置与注解,在编写接口代码过程中,同时也把接口文档写好,接口需要变更时,文档也同时变更,具有工作量少,效率高,接口文档直观简洁,可实时调用验证等好处。

代码下载

默认访问接口文档地址:http://域名:端口号/swagger-ui/index.html?configUrl=/v3/api-docs/swagger-config#/

可以使用配置方式自定义访问地址,然后会自动重定向到上面的地址去。

代码部分截图:

SpringBoot 集成 SpringDoc-OpenAPI

为什么不直接用 Swagger?

由于 SpringDoc-OpenAPI 3 提供了与 Swagger 的整合包,并且 Swagger 更新缓慢,而 SpringDoc 还在保持更新,所以这里直接介绍SoringDoc-OpenAPI 3 的使用,如果以前使用过 Swagger,要迁移到 OpenAPI 是十分简单的。

迁移文档:Migrating from SpringFox

由于集成 SpringDoc-OpenAPI 比较简单,所以直接将迁移文档中的内容翻译过来。

Migrating from SpringFox

  • 移除 Springfox 和 swagger 2 的依赖。使用如下 springdoc-openapi-ui的依赖替代。
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-ui</artifactId>
    <version>1.4.5</version>
</dependency>
  • Replace swagger 2 annotations with swagger 3 annotations (it is already included with springdoc-openapi-ui dependency). Package for swagger 3 annotations is io.swagger.v3.oas.annotations.

  • 将 Swagger2 中的注解用 Swagger 3 的注解替换(前提是必须要先导入上文中的依赖)。Swagger 3 的注解所在包为 io.swagger.v3.oas.annotations

    Swagger 2 中的注解Swagger 3 中的替代注解
    @Api@Tag
    @ApiIgnore@Parameter(hidden = true) 或 @Operation(hidden = true) 或 @Hidden
    @ApiImplicitParam@Parameter
    @ApiImplicitParams@Parameters
    @ApiModel@Schema
    @ApiModelProperty(hidden = true)@Schema(accessMode = READ_ONLY)
    @ApiModelProperty@Schema
    @ApiOperation(value = "foo", notes = "bar")@Operation(summary = "foo", description = "bar")
    @ApiParam@Parameter
    @ApiResponse(code = 404, message = "foo")@ApiResponse(responseCode = "404", description = "foo")
  • 这个步骤是可选的:只有当您有多个 Docket bean 时,才将它们替换为 GroupedOpenApi bean。

    Before:

    @Bean
    public Docket publicApi() {
        return new Docket(DocumentationType.SWAGGER_2)
            .select()
            .apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.public"))
            .paths(PathSelectors.regex("/public.*"))
            .build()
            .groupName("springshop-public")
            .apiInfo(apiInfo());
    }
    
    @Bean
    public Docket adminApi() {
        return new Docket(DocumentationType.SWAGGER_2)
            .select()
            .apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.admin"))
            .paths(PathSelectors.regex("/admin.*"))
            .build()
            .groupName("springshop-admin")
            .apiInfo(apiInfo());
    }
    

    Now:

    @Bean
    public GroupedOpenApi publicApi() {
        return GroupedOpenApi.builder()
            .setGroup("springshop-public")
            .pathsToMatch("/public/**")
            .build();
    }
    
    @Bean
    public GroupedOpenApi adminApi() {
        return GroupedOpenApi.builder()
            .setGroup("springshop-admin")
            .pathsToMatch("/admin/**")
            .build();
    }
    

    如果你只有一个 Docket,那么直接移除它并且将配置信息添加到你自己的 application.yml 中:

    springdoc:
        packagesToScan: package1, package2
        pathsToMatch: /v1, /api/balance/**
    
  • 在 config 配置类中添加一个 OpenAPI 类型的 bean。看下面例子:
    @Bean
    public OpenAPI springShopOpenAPI() {
        return new OpenAPI()
            .info(new Info()
                  .title("SpringShop API")
                  .description("Spring shop sample application")
                  .version("v0.0.1")
                  .license(new License().name("Apache 2.0").url("http://springdoc.org")))
            .externalDocs(new ExternalDocumentation()
                          .description("SpringShop Wiki Documentation")
                          .url("https://springshop.wiki.github.org/docs"));
    }
    
  • 如果 Swagger UI 有使用反向代理:

    https://springdoc.org/faq.html#how-can-i-deploy-the-doploy-springdoc-openapi-ui-behind-a-reverse-proxy.

  • 自定义 Swagger UI:

    https://springdoc.org/faq.html#how-can-i-configure-swagger-ui.

  • 在文档中隐藏接口方法或控制器:

    https://springdoc.org/faq.html#how-can-i-hide-an-operation-or-a-controller-from-documentation-.


前天遇到了小鹿,昨天是小兔子,今天是你。