Swagger官方API


Swagger快速使用

Swagger简介

Swagger 是一个规范且完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。

Swagger 是一套基于 OpenAPI 规范(OpenAPI Specification,OAS)构建的开源工具,后来成为了 Open API 标准的主要定义者,现在最新的版本为17年发布的 Swagger3(Open Api3)。 国内绝大部分人还在用过时的swagger2(17年停止维护并更名为swagger3) 对于 Rest API 来说很重要的一部分内容就是文档,Swagger 为我们提供了一套通过代码和注解自动生成文档的方法,这一点对于保证API 文档的及时性将有很大的帮助。 OAS本身是一个API规范,它用于描述一整套API接口,包括一个接口是哪种请求方式、哪些参数、哪些header等,都会被包括在这个文件中。它在设计的时候通常是YAML格式,这种格式书写起来比较方便,而在网络中传输时又会以json形式居多,因为json的通用性比较强。 SpringFox是 spring 社区维护的一个项目(非官方),帮助使用者将 swagger2 集成到 Spring 中。

Swagger 的目标是对 REST API 定义一个标准且和语言无关的接口,可以让人和计算机拥有无须访问源码、文档或网络流量监测就可以发现和理解服务的能力。当通过 Swagger 进行正确定义,用户可以理解远程服务并使用最少实现逻辑与远程服务进行交互。与为底层编程所实现的接口类似,Swagger 消除了调用服务时可能会有的猜测。

Swagger 主要包含了以下三个部分:

  • Swagger Editor:基于浏览器的编辑器,我们可以使用它编写我们 OpenAPI 规范。
  • Swagger UI:它会将我们编写的 OpenAPI 规范呈现为交互式的 API 文档,后文我将使用浏览器来查看并且操作我们的 Rest API。
  • Swagger Codegen:它可以通过为 OpenAPI(以前称为 Swagger)规范定义的任何 API 生成服务器存根和客户端 SDK 来简化构建过程。

Swagger 的优势

  • 支持 API 自动生成同步的在线文档:使用 Swagger 后可以直接通过代码生成文档,不再需要自己手动编写接口文档了,对程序员来说非常方便,可以节约写文档的时间去学习新技术。
  • 提供 Web 页面在线测试 API:光有文档还不够,Swagger 生成的文档还支持在线测试。参数和格式都定好了,直接在界面上输入参数对应的值即可在线测试接口。

集成 Swagger 管理 API 文档

1)项目中集成 Swagger

集成 Swagger 我们使用封装好了的 Starter 包,代码如下所示。

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

在启动类中使用 @EnableSwagger2Doc 开启 Swagger,代码如下所示。

@EnableSwagger2Doc
@SpringBootApplication
public class AuthApplication {
    public static void main(String[] args) {
        SpringApplication.run(AuthApplication.class, args);
    }
}

2)使用 Swagger 生成文档

Swagger 是通过注解的方式来生成对应的 API,在接口上我们需要加上各种注解来描述这个接口.

@ApiOperation(value = "新增用户")
@ApiResponses({ @ApiResponse(code = 200, message = "OK", response = UserDto.class) })
@PostMapping("/user")
public UserDto addUser(@RequestBody AddUserParam param) {
    System.err.println(param.getName());
    return new UserDto();
}

参数类定义代码如下所示。

@Data
@ApiModel(value = "com.biancheng.auth.param.AddUserParam", description = "新增用户参数")
public class AddUserParam {
    @ApiModelProperty(value = "ID")
    private String id;
    @ApiModelProperty(value = "名称")
    private String name;
    @ApiModelProperty(value = "年龄")
    private int age;
}

在线测试接口

接口查看地址可以通过服务地址 /swagger-ui.html 来访问.

可以展开看详情

在 param 中输入参数,点击 Try it out 按钮可以调用接口

SpringBoot OpenAPI3

0. Get Start

1. Introduction

springdoc-openapi java 库有助于使用 spring boot 项目自动生成 API 文档。springdoc-openapi 通过在运行时检查应用程序来根据 spring 配置、类结构和各种注释推断 API 语义。

自动生成 JSON/YAML 和 HTML 格式 API 的文档。本文档可以通过使用 swagger-api 注释的注释来完成。

该库支持:

  • 开放API 3
  • Spring-boot(v1 和 v2)
  • JSR-303,专门针对 @NotNull、@Min、@Max 和 @Size。
  • Swagger-ui
  • OAuth 2
  • GraalVM 原生镜像

2. 入门

对于spring-boot和swagger-ui的集成,把库添加到你的项目依赖列表中(不需要额外配置)

   <dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-ui</artifactId>
      <version>1.6.2</version>
   </dependency>

这将自动将 swagger-ui 部署到 spring-boot 应用程序:

  • 文档将以 HTML 格式提供,使用官方swagger-ui jars
  • Swagger UI 页面将http://server:port/context-path/swagger-ui.html在以下位置提供,OpenAPI 描述将在以下 json 格式的 url 中提供:http://server:port/context-path/v3/api-docs
    • 服务器:服务器名称或 IP
    • 端口:服务器端口
    • 上下文路径:应用程序的上下文路径
  • 文档也可以 yaml 格式提供,位于以下路径:/v3/api-docs.yaml

对于 HTML 格式的 swagger 文档的自定义路径,请在 spring-boot 配置文件中添加自定义 springdoc 属性:

# swagger-ui custom path
springdoc.swagger-ui.path=/swagger-ui.html

3. Springdoc-openapi 模块

3.1. 总体概述

3.2. Spring-webmvc 支持

  • json 格式的文档将在以下 url 处提供: http://server:port/context-path/v3/api-docs
    • 服务器:服务器名称或 IP
    • 端口:服务器端口
    • 上下文路径:应用程序的上下文路径
  • 文档也将以 yaml 格式提供,位于以下路径:/v3/api-docs.yaml
  • 将该库添加到项目依赖项列表中。(无需额外配置)
   <dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-webmvc-core</artifactId>
      <version>1.6.2</version>
   </dependency>

如果您想在不使用 swagger-ui 的情况下生成 OpenAPI 描述,则此依赖项是相关的。

对于 Json 格式的 OpenAPI 文档的自定义路径,在您的 spring-boot 配置文件中添加自定义 springdoc 属性:

# /api-docs endpoint custom path
springdoc.api-docs.path=/api-docs

3.3. Spring-webflux 支持

  • 文档也可以 yaml 格式提供,位于以下路径:/v3/api-docs.yaml
  • 将库添加到您的项目依赖项列表中(无需额外配置)
   <dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-webflux-ui</artifactId>
      <version>1.6.2</version>
   </dependency>

3.4. Spring Hateoas 支持

使用依赖 springdoc-openapi-hateoas 可以获得对 Spring Hateoas 的支持。使用 Spring Hateoas 的项目应该将此依赖项与 springdoc-openapi-ui 依赖项结合起来。这种依赖支持 Spring Hateoas 格式。

   <dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-hateoas</artifactId>
      <version>1.6.2</version>
   </dependency>

3.5. Spring Data Rest 支持

使用spring-data-rest和需要Pageable类型支持的项目可以结合依赖添加如下springdoc-openapi-ui依赖。这种依赖支持spring-boot-starter-data-rest诸如:@RepositoryRestResourceQuerydslPredicate注释之类的类型。

   <dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-data-rest</artifactId>
      <version>1.6.2</version>
   </dependency>

3.6. Spring 安全支持

对于使用 spring-security 的项目,您应该添加以下依赖项,并结合 springdoc-openapi-ui 依赖项:此依赖项有助于忽略 @AuthenticationPrincipal,以防它在 REST 控制器上使用。

   <dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-security</artifactId>
      <version>1.6.2</version>
   </dependency>

3.7. Spring 原生支持

springdoc-openapi,支持开箱即用的GraalVM原生镜像。如果应用程序使用spring-native,则应添加以下依赖项,并结合 (springdoc-openapi-uispringdoc-openapi-webflux-ui) 依赖项: - 此依赖项有助于对 springdoc-openapi 的本机支持(仅自 以来可用v1.5.13)。

   <dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-native</artifactId>
      <version>1.6.2</version>
   </dependency>

这是兼容性矩阵,它显示了经过测试/验证的版本springdoc-openapi

springdoc-openapi 版本 spring-native 版本
1.6.0 0.11.0
1.5.13 0.11-RC1
1.5.12 0.10.5
1.5.11 0.10.3
1.5.10 0.10.1
1.5.9 0.9.2

使用本机图像的 swagger-ui 的 url,包含 swagger-ui 的版本。这与 GraalVM #1108 中的以下增强请求有关。

3.8. Kotlin 支持

对于使用 Kotlin 的项目,您应该添加以下依赖项。此依赖项改进了对 Kotlin 类型的支持:

   <dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-kotlin</artifactId>
      <version>1.6.2</version>
   </dependency>
  • 如果您使用的是 spring-web,则将 springdoc-openapi-kotlin 模块与 springdoc-openapi-ui 结合使用。
  • 如果您使用的是 spring-webflux,则将 springdoc-openapi-kotlin 模块与 springdoc-openapi-webflux-ui 结合使用。

3.9. 常规支持

对于使用 Groovy 的项目,应该添加以下依赖项,结合 springdoc-openapi-ui 依赖项: 该依赖项改进了对 Kotlin 类型的支持:

   <dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-groovy</artifactId>
      <version>1.6.2</version>
   </dependency>

3.10. Javadoc 支持

对于想要启用 javadoc 支持的项目,您应该添加以下依赖项,并结合springdoc-openapi-ui依赖项:

   <dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-javadoc</artifactId>
      <version>1.6.2</version>
   </dependency>

此依赖项改进了对 javadoc 标记和注释的支持:

  • 方法的 javadoc 注释:解析为@Operation描述
  • @return: 解析为@Operation响应描述
  • 属性的 javadoc 注释:被解析为此字段的“@Schema”描述。

此依赖项基于库therapi-runtime-javadoc

确保您启用了注解处理器,therapi-runtime-javadoc以便为 springdoc-openapi 启用 javadoc 支持。

  <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>com.github.therapi</groupId>
                            <artifactId>therapi-runtime-javadoc-scribe</artifactId>
                            <version>0.12.0</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>

如果同时存在 swagger-annotation 描述和 javadoc 注释。将使用 swagger-annotation 描述的值。

4. Springdoc-openapi 特性

4.1. 添加 API 信息和安全文档

该库使用 spring-boot 应用程序自动配置的包来扫描 spring bean 中的以下注释:OpenAPIDefinition 和 Info。这些注解声明,API 信息:标题、版本、许可证、安全性、服务器、标签、安全性和 externalDocs。为了获得更好的文档生成性能,请在 spring 管理的 bean 中声明 @OpenAPIDefinition 和 @SecurityScheme 注释。

4.2. 使用 @ControllerAdvice 处理 REST 的错误

要自动生成文档,请确保所有方法都使用以下注释声明 HTTP 代码响应:@ResponseStatus

4.3. 禁用 springdoc-openapi 端点

为了禁用 springdoc-openapi 端点(默认为 /v3/api-docs),请使用以下属性:

# Disabling the /v3/api-docs enpoint
springdoc.api-docs.enabled=false

4.4. 禁用 swagger-ui

要禁用 swagger-ui,请使用以下属性:

# Disabling the swagger-ui
springdoc.swagger-ui.enabled=false

4.5. Swagger-ui 配置

该库支持 swagger-ui 官方属性:

您需要将 swagger-ui 属性声明为 spring-boot 属性。所有这些属性都应使用以下前缀声明:springdoc.swagger-ui

4.6. 选择要包含在文档中的 Rest Controllers

除了来自 swagger-annotations 的 @Hidden 注释之外,还可以使用包或路径配置来限制生成的 OpenAPI 描述。

对于要包含的包列表,请使用以下属性:

# Packages to include
springdoc.packagesToScan=com.package1, com.package2

对于要包含的路径列表,请使用以下属性:

# Paths to include
springdoc.pathsToMatch=/v1, /api/balance/**

4.7. 带有功能端点的 Spring-webflux/WebMvc.fn

从 v1.5.0 版本开始,由于 spring-framework 中的这一增强,引入了功能性 DSL:#25938

它是@RouterOperations注释的替代功能 API 。

这是一个示例 DSL,用于为 webflux/WebMvc.fn REST 端点生成 OpenAPI 描述:

@Bean
RouterFunction<?> routes() {
    return route().GET("/foo", HANDLER_FUNCTION, ops -> ops
            .operationId("hello")
            .parameter(parameterBuilder().name("key1").description("My key1 description"))
            .parameter(parameterBuilder().name("key2").description("My key2 description"))
            .response(responseBuilder().responseCode("200").description("This is normal response description"))
            .response(responseBuilder().responseCode("404").description("This is another response description"))
    ).build();
}

这是一些示例代码的链接:

以及使用功能端点 DSL 的演示代码:

从 v1.3.8 版本开始,增加了对功能端点的支持。为此目的添加了两个主要注释:@RouterOperations@RouterOperation.

只有带有@RouterOperations和 的REST API@RouterOperation才能显示在 swagger-ui 上。

  • @RouterOperation: 可以单独使用,如果Router bean包含一个与REST API相关的单一路由..使用@RouterOperation时,不需要填写路径
  • @RouterOperation,可以直接引用一个spring Bean(beanClass属性)和底层方法(beanMethod属性):Springdoc-openapi,然后会检查这个方法和这个方法级别的swagger注解。
@Bean
@RouterOperation(beanClass = EmployeeService.class, beanMethod = "findAllEmployees")
RouterFunction<ServerResponse> getAllEmployeesRoute() {
   return route(GET("/employees").and(accept(MediaType.APPLICATION_JSON)),
         req -> ok().body(
               employeeService().findAllEmployees(), Employee.class));
}
  • @RouterOperation, 包含@Operation注释。该@Operation注释也可以放置在bean的方法级别,如果该属性beanMethod声明。

不要忘记设置operationId这是强制性的

@Bean
@RouterOperation(operation = @Operation(operationId = "findEmployeeById", summary = "Find purchase order by ID", tags = { "MyEmployee" },
      parameters = { @Parameter(in = ParameterIn.PATH, name = "id", description = "Employee Id") },
      responses = { @ApiResponse(responseCode = "200", description = "successful operation", content = @Content(schema = @Schema(implementation = Employee.class))),
            @ApiResponse(responseCode = "400", description = "Invalid Employee ID supplied"),
            @ApiResponse(responseCode = "404", description = "Employee not found") }))
RouterFunction<ServerResponse> getEmployeeByIdRoute() {
   return route(GET("/employees/{id}"),
         req -> ok().body(
               employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class));
}
  • @RouterOperations: 如果 Router bean 包含多个路由,则应使用此注释。使用 RouterOperations 时,必须填写 path 属性。
  • A @RouterOperations、包含很多@RouterOperation
@RouterOperations({ @RouterOperation(path = "/getAllPersons", beanClass = PersonService.class, beanMethod = "getAll"),
      @RouterOperation(path = "/getPerson/{id}", beanClass = PersonService.class, beanMethod = "getById"),
      @RouterOperation(path = "/createPerson", beanClass = PersonService.class, beanMethod = "save"),
      @RouterOperation(path = "/deletePerson/{id}", beanClass = PersonService.class, beanMethod = "delete") })
@Bean
public RouterFunction<ServerResponse> personRoute(PersonHandler handler) {
   return RouterFunctions
         .route(GET("/getAllPersons").and(accept(MediaType.APPLICATION_JSON)), handler::findAll)
         .andRoute(GET("/getPerson/{id}").and(accept(MediaType.APPLICATION_STREAM_JSON)), handler::findById)
         .andRoute(POST("/createPerson").and(accept(MediaType.APPLICATION_JSON)), handler::save)
         .andRoute(DELETE("/deletePerson/{id}").and(accept(MediaType.APPLICATION_JSON)), handler::delete);
}

使用@RouterOperation 填写的所有文档,可能由路由器功能数据完成。为此,@RouterOperation 字段必须帮助唯一标识相关路由。springdoc-openpi 使用以下条件扫描与 @RouterOperation 注释相关的唯一路由:

  • 按路径
  • 按路径和请求方法
  • 通过路径并产生
  • 通过路径和消耗
  • 通过路径和请求方法并产生
  • 通过路径和请求方法并消耗
  • 按路径生产和消费
  • 通过路径和请求方法并产生和消耗

演示的 GITHUB 上提供了一些代码示例:

还有一些项目测试:(从app69到app75)

4.8. 在 Actuator 端口上暴露 swagger-ui

从 release 开始1.5.1,可以在执行器端口上公开swagger-uiopenapi端点。注意:执行器管理端口必须与应用程序端口不同。

要公开 swagger-ui,在管理端口上,您应该设置

springdoc.use-management-port=true
# This property enables the openapi and swaggerui endpoints to be exposed beneath the actuator base path.
management.endpoints.web.exposure.include=openapi, swaggerui

启用后,您还应该能够在以下位置看到 springdoc-openapi 端点:(主机和端口取决于您的设置)- http://serverName:managementPort/actuator

例如,如果您有以下设置:

有两个端点可用:

  1. 包含 OpenAPI 定义的 REST API:
    • http://serverName:managementPort/actuator/openapi
  2. 一个端点,路由到 swagger-ui:
    • http://serverName:managementPort/actuator/swaggerui
management.server.port=9090

例如,您还应该能够看到 springdoc-openapi 端点:

  • http://serverName:9090/actuator
  • http://serverName:9090/actuator/swaggerui
  • http://serverName:9090/actuator/openapi

如果您想访问应用程序端点,从部署在执行器基本路径下的 swagger-ui,使用与您的应用程序不同的端口,CORS for your endpoints应在您的应用程序级别启用。

此外,还可以将此属性与现有属性相结合,以在 swagger-ui 中显示执行器端点。

springdoc.show-actuator=true

启用后: - 默认情况下将添加执行器端点的专用组。- 如果没有为应用程序定义组,则会添加一个默认组。

然后可以通过执行器端口访问 swagger-ui:- http://serverName:managementPort/actuator/swaggerui

如果管理端口与应用程序端口不同并且 ‘springdoc.use-management-port’ 未定义但 ‘springdoc.show-actuator’ 设置为 true:

启用后: - 然后可以通过应用程序端口访问 swagger-ui。例如:http://serverName:applicationPort/swagger-ui.html - 默认情况下将添加执行器端点的专用组。- 如果没有为应用程序定义组,则会添加一个默认组。

如果您想访问这种情况下的执行器端点(与您的应用程序不同的端口),CORS则应启用执行器端点。

注意:现在无法自定义执行器基本路径下这些新端点的命名。

4.9. 与 WildFly 集成

  • 对于 WildFly 用户,您需要添加以下依赖项才能使 swagger-ui 工作:
   <dependency>
     <groupId>org.webjars</groupId>
     <artifactId>webjars-locator-jboss-vfs</artifactId>
     <version>0.1.0</version>
   </dependency>

5. Springdoc-openapi 属性

springdoc-openapi 依赖于使用标准文件位置的标准spring 配置属性(yml 或属性)。

5.1. springdoc-openapi 核心属性

参数名称 默认值 描述
springdoc.api-docs.path /v3/api-docs String, 用于自定义 Json 格式的 OpenAPI 文档路径。
springdoc.api-docs.enabled true Boolean. 禁用 springdoc-openapi 端点(默认为 /v3/api-docs)。
springdoc.packages-to-scan * List of Strings.要扫描的包列表(逗号分隔)
springdoc.paths-to-match /* List of Strings.要匹配的路径列表(逗号分隔)
springdoc.produces-to-match /* List of Strings.要匹配的生产媒体类型列表(逗号分隔)
springdoc.headers-to-match /* List of Strings.要匹配的标题列表(逗号分隔)
springdoc.consumes-to-match /* List of Strings.要匹配的消耗媒体类型列表(逗号分隔)
springdoc.paths-to-exclude List of Strings.要排除的路径列表(逗号分隔)
springdoc.packages-to-exclude List of Strings.要排除的包列表(逗号分隔)
springdoc.default-consumes-media-type application/json String. 默认使用媒体类型。
springdoc.default-produces-media-type **/** String.默认产生媒体类型。
springdoc.cache.disabled false Boolean. 禁用计算出来的 OpenAPI 的 springdoc-openapi 缓存。
springdoc.show-actuator false Boolean. 显示执行器端点。
springdoc.auto-tag-classes true Boolean. 禁用 springdoc-openapi 自动标签。
springdoc.model-and-view-allowed false Boolean. 允许带有 ModelAndView 的 RestControllers 返回出现在 OpenAPI 描述中。
springdoc.override-with-generic-response true Boolean. 当为 true 时,自动将 @ControllerAdvice 响应添加到所有生成的响应中。
springdoc.api-docs.groups.enabled true Boolean. 禁用 springdoc-openapi 组。
springdoc.group-configs[0].group String.组名
springdoc.group-configs[0].packages-to-scan * List of Strings.要扫描的包列表(逗号分隔)
springdoc.group-configs[0].paths-to-match /* List of Strings. 匹配组的路径列表(逗号分隔)
springdoc.group-configs[0].paths-to-exclude `` List of Strings.要排除的路径列表(逗号分隔)
springdoc.group-configs[0].packages-to-exclude List of Strings.要排除的包列表(逗号分隔)
springdoc.group-configs[0].produces-to-match /* List of Strings.要匹配的生产媒体类型列表(逗号分隔)
springdoc.group-configs[0].consumes-to-match /* List of Strings.要匹配的消耗媒体类型列表(逗号分隔)
springdoc.group-configs[0].headers-to-match /* List of Strings.要匹配的标题列表(逗号分隔)
springdoc.webjars.prefix /webjars String, 要更改可见的 webjars 前缀,请更改 spring-webflux 的 swagger-ui 的 URL。
springdoc.api-docs.resolve-schema-properties false Boolean. 在@Schema 上启用属性解析器(名称、标题和描述)。
springdoc.remove-broken-reference-definitions true Boolean. 禁止删除损坏的参考定义。
springdoc.writer-with-default-pretty-printer false Boolean. 启用 OpenApi 规范的漂亮打印。
springdoc.model-converters。弃用-converter.enabled true Boolean. 禁用弃用模型转换器。
springdoc.model-converters.polymorphic-converter.enabled true Boolean. 禁用多态模型转换器。
springdoc.model-converters.pageable-converter.enabled true Boolean. 禁用可分页模型转换器。
springdoc.use-fqn false Boolean. 启用完全限定名称。
springdoc.show-login-endpoint false Boolean. 使 spring 安全登录端点可见。
springdoc.pre-loading-enabled false Boolean. 在应用程序启动时加载 OpenAPI 的预加载设置。
springdoc.writer-with-order-by-keys false Boolean. 启用确定性/字母顺序。
springdoc.use-management-port false Boolean. 在执行器管理端口上公开 swagger-ui。
springdoc.disable-i18n false Boolean. 使用 i18n 禁用自动翻译。

5.2. swagger-ui 属性

  • 对 swagger-ui 属性的支持可在springdoc-openapi. 请参阅官方文档
  • 您可以在文档中使用与 Spring Boot 属性相同的 swagger-ui 属性。

所有这些属性都应使用以下前缀声明: springdoc.swagger-ui

参数名称 默认值 描述
springdoc.swagger-ui.path /swagger-ui.html String, 用于 swagger-ui HTML 文档的自定义路径。
springdoc.swagger-ui.enabled true Boolean. 禁用 swagger-ui 端点(默认为 /swagger-ui.html)。
springdoc.swagger-ui.configUrl /v3/api-docs/swagger-config String. 从中获取外部配置文档的 URL。
springdoc.swagger-ui.layout BaseLayout String. 可通过插件系统用作 Swagger UI 的顶级布局的组件的名称。
springdoc.swagger-ui.validatorUrl validator.swagger.io/validator 默认情况下,Swagger UI 尝试根据 swagger.io 的在线验证器验证规范。您可以使用此参数设置不同的验证器 URL,例如为本地部署的验证器Validator Badge。将其设置为none,127.0.0.1localhost将禁用验证。
springdoc.swagger-ui.tryItOutEnabled false Boolean. 控制是否应默认启用“试用”部分。
springdoc.swagger-ui.filter false Boolean OR String. 如果设置,则启用过滤。顶部栏将显示一个编辑框,您可以使用它来过滤显示的标记操作。可以是布尔值以启用或禁用,也可以是字符串,在这种情况下,将使用该字符串作为过滤器表达式来启用过滤。过滤区分大小写,匹配标签内任何地方的过滤器表达式。
springdoc.swagger-ui.operationsSorter Function=(a ⇒ a). 对每个 API 的操作列表应用排序。它可以是“alpha”(按字母数字路径排序)、“method”(按 HTTP 方法排序)或函数(请参阅 Array.prototype.sort() 以了解排序函数的工作原理)。默认是服务器返回的顺序不变。
springdoc.swagger-ui.tagsSorter Function=(a ⇒ a). 对每个 API 的标签列表应用排序。它可以是“alpha”(按字母数字路径排序)或函数,请参阅 Array.prototype.sort()以了解如何编写排序函数)。每次通过时,都会将两个标签名称字符串传递给分拣机。默认是 Swagger UI 确定的顺序。
springdoc.swagger-ui.oauth2RedirectUrl /swagger-ui/oauth2-redirect.html String. OAuth 重定向 URL。
springdoc.swagger-ui.displayOperationId false Boolean. 控制操作列表中 operationId 的显示。默认为false
springdoc.swagger-ui.displayRequestDuration false Boolean. 控制“试用”请求的请求持续时间(以毫秒为单位)的显示。
springdoc.swagger-ui.deepLinking false Boolean. 如果设置为true,则启用标签和操作的深层链接。有关详细信息,请参阅 深层链接文档
springdoc.swagger-ui.defaultModelsExpandDepth 1 Number. 模型的默认扩展深度(设置为 -1 完全隐藏模型)。
springdoc.swagger-ui.defaultModelExpandDepth 1 Number. 模型示例部分中模型的默认扩展深度。
springdoc.swagger-ui.defaultModelRendering String=["example"*, "model"]. 控制首次呈现 API 时模型的显示方式。(用户始终可以通过单击“模型”和“示例值”链接来切换给定模型的渲染。)
springdoc.swagger-ui.docExpansion String=["list"*, "full", "none"]. 控制操作和标签的默认扩展设置。它可以是“list”(仅展开标签)、“full”(展开标签和操作)或“none”(不展开任何内容)。
springdoc.swagger-ui.maxDisplayedTags Number. 如果设置,将显示的标记操作数量限制为最多这么多。默认是显示所有操作。
springdoc.swagger-ui.showExtensions false Boolean. 控制供应商扩展 ( x-) 字段和操作、参数和架构值的显示。
springdoc.swagger-ui.url String.要配置,自定义 OpenAPI 文件的路径。如果urls使用将被忽略。
springdoc.swagger-ui.showCommonExtensions false Boolean. 控制参数的扩展(patternmaxLengthminLengthmaximumminimum)字段和值的显示。
springdoc.swagger-ui.supportedSubmitMethods Array=["get", "put", "post", "delete", "options", "head", "patch", "trace"]. 启用了“试用”功能的 HTTP 方法列表。空数组禁用所有操作的“试用”。这不会从显示中过滤操作。
springdoc.swagger-ui.queryConfigEnabled false Boolean. 自禁用v1.6.0。此参数通过 URL 搜索参数启用(旧版)覆盖配置参数。在启用此功能之前,请参阅安全公告
springdoc.swagger-ui.oauth。附加查询字符串参数 String. 添加到authorizationUrl 和tokenUrl 的附加查询参数。
springdoc.swagger-ui.disable-swagger-default-url false Boolean. 禁用 swagger-ui 默认 petstore url。(自 v1.4.1 起可用)。
springdoc.swagger-ui.urls[0].url URL. swagger 组的 url,由 Topbar 插件使用。URL 在此数组中的所有项目中必须是唯一的,因为它们用作标识符。
springdoc.swagger-ui.urls[0].name String. Topbar 插件使用的 swagger 组的名称。名称在此数组中的所有项目中必须是唯一的,因为它们用作标识符。
springdoc.swagger-ui.urlsPrimaryName String. Swagger UI 加载时将显示的 swagger 组的名称。
springdoc.swagger-ui.oauth.clientId String. 默认客户端 ID。必须是字符串。
springdoc.swagger-ui.oauth.clientSecret String. 默认客户端机密。切勿在您的生产环境中使用此参数。它暴露了关键的安全信息。此功能仅适用于开发/测试环境。
springdoc.swagger-ui.oauth.realm String. 领域查询参数(用于 OAuth 1)添加到 authorizationUrl 和 tokenUrl。
springdoc.swagger-ui.oauth.appName String. OAuth 应用程序名称,显示在授权弹出窗口中。
springdoc.swagger-ui.oauth.scopeSeparator String. 用于传递范围的 OAuth 范围分隔符,在调用前编码,默认值为空格(编码值 %20)。
springdoc.swagger-ui.csrf.enabled false Boolean. 启用 CSRF 支持
springdoc.swagger-ui.csrf.cookie-name XSRF-TOKEN String. 可选 CSRF,设置 CSRF cookie 名称。
springdoc.swagger-ui.csrf.header-name X-XSRF-TOKEN String. 可选的 CSRF,设置 CSRF 头名称。
springdoc.swagger-ui.syntaxHighlight.activated true Boolean. 是否应激活语法突出显示。
springdoc.swagger-ui.syntaxHighlight.theme agate String. String=["agate"*, "arta", "monokai", "nord", "obsidian", "tomorrow-night"]. 要使用的Highlight.js语法着色主题。(仅提供这 6 种样式。)
springdoc.swagger-ui.oauth。useBasicAuthentication WithAccessCodeGrant false Boolean. 仅针对 accessCode 流激活。在对 tokenUrl 的 authorization_code 请求期间,使用 HTTP 基本身份验证方案(具有基本 base64encode(client_id + client_secret) 的授权标头)传递客户端密码。
springdoc.swagger-ui.oauth。usePkceWithAuthorization CodeGrant false Boolean.仅适用于授权码流。代码交换证明密钥为 OAuth 公共客户端带来了增强的安全性。
springdoc.swagger-ui.persistAuthorization false Boolean. 如果设置为 true,它会保留授权数据,并且不会在浏览器关闭/刷新时丢失
springdoc.swagger-ui.use-root-path false Boolean. 如果设置为 true,则可以直接从应用程序根路径访问 swagger-ui。

6. Springdoc-openapi 插件

6.1. Maven插件

springdoc-openapi-maven-plugin 的目的是在构建时生成 json 和 yaml OpenAPI 描述。该插件在集成测试阶段工作,并生成 OpenAPI 描述。该插件与 spring-boot-maven 插件配合使用。

您可以在集成测试阶段使用 maven 命令对其进行测试:

mvn verify

为了使用这个功能,你需要在 pom.xml 的 plugins 部分添加插件声明:

<plugin>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-maven-plugin</artifactId>
 <version>2.3.4.RELEASE</version>
 <configuration>
    <jvmArguments>-Dspring.application.admin.enabled=true</jvmArguments>
 </configuration>
 <executions>
  <execution>
   <id>pre-integration-test</id>
   <goals>
    <goal>start</goal>
   </goals>
  </execution>
  <execution>
   <id>post-integration-test</id>
   <goals>
    <goal>stop</goal>
   </goals>
  </execution>
 </executions>
</plugin>
<plugin>
 <groupId>org.springdoc</groupId>
 <artifactId>springdoc-openapi-maven-plugin</artifactId>
 <version>1.3</version>
 <executions>
  <execution>
   <id>integration-test</id>
   <goals>
    <goal>generate</goal>
   </goals>
  </execution>
 </executions>
</plugin>

springdoc-openapi-maven-plugin的更多自定义设置可以参考插件文档:

6.2. Gradle插件

此插件允许您从 Gradle 构建为 Spring Boot 应用程序生成 OpenAPI 3 规范。

plugins {
      id("org.springframework.boot") version "2.3.0.RELEASE"
      id("com.github.johnrengelman.processes") version "0.5.0"
      id("org.springdoc.openapi-gradle-plugin") version "1.3.3"
}

当您将此插件及其运行时依赖项插件添加到您的构建文件时,该插件会创建以下任务:

  • 分叉的SpringBootRun
  • 生成OpenApiDocs
gradle clean generateOpenApiDocs

更多关于 springdoc-openapi-gradle-plugin 的自定义配置,可以参考插件文档:

7. Springdoc-openapi 演示

7.1. springdoc 应用程序演示

7.2. 演示应用程序的源代码

8. 从 SpringFox 迁移

  • 删除 springfox 和 swagger 2 依赖项。添加springdoc-openapi-ui依赖项。
   <dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-ui</artifactId>
      <version>1.6.2</version>
   </dependency>
  • 用 swagger 3 注释替换 swagger 2 注释(它已经包含在springdoc-openapi-ui依赖项中)。swagger 3 注释的包是io.swagger.v3.oas.annotations.
    • @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")
  • 此步骤是可选的:仅当您有多个 Docketbean 时将它们替换为GroupedOpenApibean。

前:

  @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());
  }

现在:

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

如果您只有一个 Docket - 将其删除,而是将属性添加到您的application.properties:

springdoc.packagesToScan=package1, package2
springdoc.pathsToMatch=/v1, /api/balance/**
  • 添加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"));
  }

9. 其他资源

9.1. 其他入门资源

9.2. 依赖库

springdoc-openapi 库托管在 maven 中央存储库上。可以在以下位置查看工件:

发布:

快照:

10. 特别感谢

  • 感谢Spring 团队分享有关 Spring 项目的所有相关资源。
  • 非常感谢JetBrains对 springdoc-openapi 项目的支持。

11. 常见问题

11.1. 如何在一个 Spring Boot 项目中定义多个 OpenAPI 定义?

您可以根据以下组合定义自己的 API 组:要扫描的 API 路径和包。每个组都应该有一个唯一的groupName. 该组的 OpenAPI 描述,默认情况下可用于:

  • http://server:port/context-path/v3/api-docs/groupName

为了支持多个 OpenAPI 定义,GroupedOpenApi需要定义一个类型的 bean 。

对于以下 Group 定义(基于包路径),OpenAPI 描述 URL 将为:/v3/api-docs/ stores

@Bean
public GroupedOpenApi storeOpenApi() {
   String paths[] = {"/store/**"};
   return GroupedOpenApi.builder().group("stores").pathsToMatch(paths)
         .build();
}

对于以下组定义(基于包名称),OpenAPI 描述 URL 将为:/v3/api-docs/ users

@Bean
public GroupedOpenApi userOpenApi() {
   String packagesToscan[] = {"test.org.springdoc.api.app68.api.user"};
   return GroupedOpenApi.builder().group("users").packagesToScan(packagesToscan)
         .build();
}

对于以下 Group 定义(基于路径),OpenAPI 描述 URL 将为:/v3/api-docs/ pets

@Bean
public GroupedOpenApi petOpenApi() {
   String paths[] = {"/pet/**"};
   return GroupedOpenApi.builder().group("pets").pathsToMatch(paths)
         .build();
}

对于以下 Group 定义(基于包名称和路径),OpenAPI 描述 URL 将为:/v3/api-docs/ groups

@Bean
public GroupedOpenApi groupOpenApi() {
   String paths[] = {"/v1/**"};
   String packagesToscan[] = {"test.org.springdoc.api.app68.api.user", "test.org.springdoc.api.app68.api.store"};
   return GroupedOpenApi.builder().group("groups").pathsToMatch(paths).packagesToScan(packagesToscan)
         .build();
}

关于使用的更多详细信息,您可以查看以下示例测试:

11.2. 如何配置 Swagger UI?

  • 对 swagger 官方属性的支持可在springdoc-openapi. 请参阅官方文档
  • 您可以在文档中使用与 Spring Boot 属性相同的 swagger 属性。

所有这些属性都应使用以下前缀声明: springdoc.swagger-ui

11.3. 如何按提供的组过滤输出规范中记录的资源?

  • 您可以使用标准swagger-ui属性过滤器。
springdoc.swagger-ui.filter=group-a

11.4. 如何根据环境变量禁用/启用 Swagger UI 生成?

  • 此属性可帮助您仅禁用 UI。
springdoc.swagger-ui.enabled=false

11.5. 如何在 Swagger UI 中控制操作和标签的默认扩展设置,

  • 您可以在 application.yml 中设置此属性,例如:
springdoc.swagger-ui.doc-expansion=无

11.6. 如何更改 的布局swagger-ui

  • 对于布局选项,您可以使用 swagger-ui 配置选项。例如:
springdoc.swagger-ui.layout=BaseLayout

11.7. 如何按字母顺序对端点进行排序?

  • 您可以使用以下springdoc-openapi属性:
#按字母顺序排列端点
springdoc.swagger-ui.operationsSorter=alpha #
按字母顺序排列标签
springdoc.swagger-ui.tagsSorter=alpha

11.8. 如何禁用试用按钮?

  • 您必须设置以下属性:
springdoc.swagger-ui.supportedSubmitMethods="get", "put", "post", "delete", "options", "head", "patch", "trace"

11.9. 如何添加可重用枚举?

  • 你应该添加@Schema(enumAsRef = true)你的枚举。

11.10. 如何明确设置要过滤的路径?

  • 您可以使用以下属性设置要包含的路径列表:
springdoc.pathsToMatch=/v1, /api/balance/**

11.11. 如何明确设置要扫描的包?

  • 您可以使用以下属性设置要包含的包列表:
springdoc.packagesToScan=package1, package2

11.12. 如何忽略模型的某些领域?

  • 您可以在要隐藏的字段顶部使用以下注释:
  • @Schema(hidden = true)

11.13. 如何忽略@AuthenticationPrincipalspring-security 的参数?

  • 解决方法是使用: @Parameter(hidden = true)
  • 对于使用 的项目spring-security,您应该添加以下依赖项,并结合springdoc-openapi-ui依赖项:
<dependency>
   <groupId>org.springdoc</groupId>
   <artifactId>springdoc-openapi-security</artifactId>
   <version>last.version</version>
</dependency>

11.14. 有可用的 Gradle 插件吗?

11.15. 如何从文档中隐藏参数?

  • 您可以使用 @Parameter(hidden = true)

11.16. 是否@Parameters支持注释?

  • 是的

11.17. 是否springdoc-openapi支持 Jersey?

11.18. 可springdoc-openapi仅生成API @RestController

  • @RestController在类型级别上相当于@Controller+ @RequestMapping
  • 对于某些遗留应用程序,我们仍然必须同时支持两者。
  • 如果您需要@Controller在类型级别隐藏,在这种情况下,您可以使用:@Hidden在控制器级别。
  • 请注意,此注释还可用于从生成的文档中隐藏某些方法。

11.19. 是否支持以下验证注释:@NotEmpty @NotBlank @PositiveOrZero @NegativeOrZero?

  • 是的

11.20. 如何Pageable在 Swagger UI 中将 (spring-date-commons) 对象映射到正确的 URL 参数?

springdoc-openapi v1.6.0. 为此,您必须将@ParameterObject注解与Pageable类型结合起来。

之前springdoc-openapi v1.6.0: * 您也可以使用 as well@ParameterObject而不是@PageableAsQueryParamHTTPGET方法。

static {
    getConfig().replaceParameterObjectWithClass(org.springframework.data.domain.Pageable.class, Pageable.class)
            .replaceParameterObjectWithClass(org.springframework.data.domain.PageRequest.class, Pageable.class);
}
  • 另一种解决方案是手动配置 Pageable:
    • 您必须将 Pageable 字段的显式映射声明为 Query Params 并@Parameter(hidden = true) Pageable pageable在 pageable 参数上添加。
    • 您还应该@PageableAsQueryParam在方法级别声明 springdoc 提供的注解,或者如果需要定义您的自定义描述、defaultValue、…

如果要禁用 spring Pageable Type 的支持,可以使用:

springdoc.model-converters.pageable-converter.enabled=false

该属性springdoc.model-converters.pageable-converter.enabled仅自 v1.5.11+ 起可用

11.21. 如何在生成的描述中生成枚举?

  • 您可以添加一个属性allowableValues, 到@Parameter。例如:
@GetMapping("/example")
public Object example(@Parameter(name ="json", schema = @Schema(description = "var 1",type = "string", allowableValues = {"1", "2"}))
String json) {
   return null;
}
  • 或者你可以覆盖toString你的枚举:
@Override
@JsonValue
public String toString() {
   return String.valueOf(action);
}

11.22. 它真的支持 Spring Boot 2.2.x.RELEASE & HATEOAS 1.0 吗?

  • 是的

11.23. 如何部署springdoc-openapi-ui在反向代理后面?

  • 如果您的应用程序在代理、负载平衡器或云中运行,请求信息(如主机、端口、方案……)可能会在此过程中发生变化。您的应用程序可能正在运行10.10.10.10:8080,但 HTTP 客户端应该只能看到example.org.
  • RFC7239“Forwarded Headers”定义了转发的HTTP头;代理可以使用此标头提供有关原始请求的信息。您可以将应用程序配置为读取这些标头,并在创建链接并将它们以 HTTP 302 响应、JSON 文档或 HTML 页面发送给客户端时自动使用该信息。还有一些非标准的标题,如:X-Forwarded-HostX-Forwarded-PortX-Forwarded-ProtoX-Forwarded-Ssl,和X-Forwarded-Prefix
  • 如果代理添加了常用的X-Forwarded-Forand X-Forwarded-Proto headers,将 server.forward-headers-strategy 设置为 NATIVE 就足以支持这些。有了这个选项,Web 服务器本身就支持这个特性;您可以查看他们的特定文档以了解特定行为。
  • 您需要确保在反向代理配置中设置了以下标头: X-Forwarded-Prefix
  • 例如使用Apache 2,配置:
RequestHeader=set X-Forwarded-Prefix "/custom-path"
  • 然后,在您的 Spring Boot 应用程序中,确保您的应用程序处理此标头:X-Forwarded-For. 有两种方法可以实现这一点:
server.use-forward-headers=true
  • 如果这还不够,Spring Framework 提供了一个ForwardedHeaderFilter. 您可以通过将 server.forward-headers-strategy 设置为 FRAMEWORK 将其注册为应用程序中的 Servlet 过滤器。
  • 从 Spring Boot 2.2 开始,这是处理反向代理标头的新属性:
server.forward-headers-strategy=framework
  • 您可以将以下 bean 添加到您的应用程序中:
@Bean
ForwardedHeaderFilter forwardedHeaderFilter() {
   return new ForwardedHeaderFilter();
}

11.24. 是否@JsonView支持 Spring MVC API 中的注释?

  • 是的

11.25. 添加springdoc-openapi-ui依赖会破坏我的public/index.html欢迎页面

  • 如果您的根目录上已经有静态内容,并且您不希望它被springdoc-openapi-ui配置覆盖,您可以定义 的自定义配置swagger-ui,以免覆盖上下文根目录中的文件配置:
  • 例如使用:
springdoc.swagger-ui.path= /swagger-ui/api-docs.html

11.26. 如何测试 Swagger UI?

11.27. 如何自定义 OpenAPI 对象?

@Bean
public OpenApiCustomiser consumerTypeHeaderOpenAPICustomiser() {
return openApi -> openApi.getPaths().values().stream().flatMap(pathItem -> pathItem.readOperations().stream())
    .forEach(operation -> operation.addParametersItem(new HeaderParameter().$ref("#/components/parameters/myConsumerTypeHeader")));
}

11.28. 如何在 Swagger UI 中包含 spring-boot-actuator 端点?

  • 为了显示spring-boot-actuator端点,您需要添加以下属性:
springdoc.show-actuator=true

11.29. 如何返回空内容作为响应?

  • 可以使用以下语法之一将空内容作为响应处理:
  • content = @Content
  • content = @Content(schema = @Schema(hidden = true))
  • 例如:
@Operation(summary = "Get thing", responses = {
      @ApiResponse(description = "Successful Operation", responseCode = "200", content = @Content(mediaType = "application/json", schema = @Schema(implementation = String.class))),
      @ApiResponse(responseCode = "404", description = "Not found", content = @Content),
      @ApiResponse(responseCode = "401", description = "Authentication Failure", content = @Content(schema = @Schema(hidden = true))) })
@RequestMapping(path = "/testme", method = RequestMethod.GET)
ResponseEntity<String> testme() {
   return ResponseEntity.ok("Hello");
}

11.30。如何支持具有多种消费媒体类型的端点?

  • 同一类上的重载方法,具有相同的 HTTP 方法和路径,因此只会生成一个 OpenAPI 操作。
  • 此外,建议@Operation在重载方法之一的级别中设置 。否则,如果在同一个重载方法中多次声明它,它可能会被覆盖。

11.31. 如何在编译时获得 yaml 和 json (OpenAPI)?

11.32. 文档中忽略的类型是什么?

11.33. 如何禁用忽略的类型:

如果您不想忽略类型、、 和其他类型Principal,请执行以下操作:Locale``HttpServletRequest

SpringDocUtils.getConfig().removeRequestWrapperToIgnore(HttpServletRequest.class)

11.34. 如何在请求中添加授权标头?

  • 您应该将@SecurityRequirement标签添加到受保护的 API。
  • 例如:
@Operation(security = { @SecurityRequirement(name = "bearer-key") })
  • 和安全定义示例:
@Bean
 public OpenAPI customOpenAPI() {
   return new OpenAPI()
          .components(new Components()
          .addSecuritySchemes("bearer-key",
          new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT")));
}

11.35. 与 Springfox 项目的区别

  • OAS 3 于 2017 年 7 月发布,并没有发布springfox支持 OAS 3 的 版本。springfox目前仅涵盖 swagger 2 与 Spring Boot 的集成。最新发布日期是 2018 年 6 月。所以,在维护方面,最近严重缺乏支持。
  • 我们决定向前推进并与社区共享我们已经在内部项目中使用的库。
  • springfox,的最大区别在于我们集成了未涵盖的新功能springfox
  • Spring Boot 和 OpenAPI 3 标准之间的集成。
  • 我们依赖swagger-annotations并且swagger-ui只依赖官方图书馆。
  • 我们支持 Spring 5 的新特性,比如spring-webflux带注释的和函数式的风格。
  • 我们尽最大努力回答所有问题并解决所有问题或增强请求

11.36. 如何使用 springdoc-openapi 迁移到 OpenAPI 3

  • springdoc-openapi和之间没有关系springfox。如果要迁移到 OpenAPI 3:
  • 删除所有依赖和相关代码到springfox
  • 添加springdoc-openapi-ui依赖
  • 如果您不想从根路径提供 UI 或与现有配置存在冲突,则只需更改以下属性:
springdoc.swagger-ui.path=/you-path/swagger-ui.html

11.37. 如何设置全局标题?

  • 您可能有具有标准 OpenAPI 描述的全局参数。
  • 如果您需要定义全局显示(在每个组内),无论组是否满足 GroupedOpenApi 上指定的条件,您都可以使用 OpenAPI Bean。
  • 您可以在全局组件部分的参数下定义通用参数,并通过$ref. 您还可以定义全局标头参数。
  • 为此,您可以覆盖 OpenAPI Bean,并在组件级别设置全局标头或参数定义。
@Bean
public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) {
 return new OpenAPI()
        .components(new Components().addSecuritySchemes("basicScheme", new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic"))
        .addParameters("myHeader1", new Parameter().in("header").schema(new StringSchema()).name("myHeader1")).addHeaders("myHeader2", new Header().description("myHeader2 header").schema(new StringSchema())))
        .info(new Info()
        .title("Petstore API")
        .version(appVersion)
        .description("This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.")
        .termsOfService("http://swagger.io/terms/")
        .license(new License().name("Apache 2.0").url("http://springdoc.org")));
}

11.38. 是否支持回调?

  • 是的

11.39. 如何定义 SecurityScheme ?

  • 您可以使用:@SecurityScheme注释。
  • 或者您可以通过覆盖 OpenAPI Bean 以编程方式定义它:
 @Bean
 public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) {
  return new OpenAPI()
   .components(new Components().addSecuritySchemes("basicScheme",
   new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic")))
   info(new Info().title("SpringShop API").version(appVersion)
   .license(new License().name("Apache 2.0").url("http://springdoc.org")));
 }

11.40。如何从文档中隐藏操作或控制器?

  • 您可以@io.swagger.v3.oas.annotations.Hidden@RestController,@RestControllerAdvice和方法级别使用注释
  • @Hidden从异常处理程序构建通用(错误)响应时,会考虑异常处理程序方法的注释@ControllerAdvice
  • 或使用: @Operation(hidden = true)

11.41. 如何配置全局安全方案?

  • 对于全局 SecurityScheme,您可以将其添加到您自己的 OpenAPI 定义中:
@Bean
public OpenAPI customOpenAPI() {
    return new OpenAPI().components(new Components()
    .addSecuritySchemes("basicScheme", new SecurityScheme()
    .type(SecurityScheme.Type.HTTP).scheme("basic"))).info(new Info().title("Custom API")
    .version("100")).addTagsItem(new Tag().name("mytag"));
}

11.42。我可以使用带有 swagger 注释的 spring 属性吗?

  • spring 属性解析器的支持@Infotitle* description* version*termsOfService
  • spring 属性解析器的支持@Info.licensename*url
  • spring 属性解析器的支持@Info.contactname* email*url
  • spring 属性解析器的支持@Operationdescription*summary
  • spring 属性解析器的支持@Parameterdescription*name
  • spring 属性解析器的支持@ApiResponsedescription
  • 也可以声明以下安全 URL @OAuthFlowopenIdConnectUrl* authorizationUrl* refreshUrl*tokenUrl
  • spring 属性解析器对@Schema: name* title* 的支持description,通过设置springdoc.api-docs.resolve-schema-propertiestrue

11.43. 服务器 URL 是如何生成的?

  • 如果文档不存在,自动生成服务器 URL 可能很有用。
  • 如果存在服务器注释,则将使用它们。

11.44. 如何禁用 springdoc-openapi 缓存?

  • 默认情况下,OpenAPI 描述计算一次,然后缓存。
  • 有时在内部和外部代理后面提供相同的 swagger-ui。一些用户希望在每个 http 请求上计算服务器 URL。
  • 为了禁用 springdoc 缓存,您必须设置以下属性:
springdoc.cache.disabled=真

11.45。如何在不使用swagger-ui?

  • 您应该springdoc-openapi-core只使用依赖项:
<dependency>
  <groupId>org.springdoc</groupId>
  <artifactId>springdoc-openapi-webmvc-core</artifactId>
  <version>latest.version</version>
</dependency>

11.46. 如何禁用springdoc-openapi端点?

  • 使用以下属性:
springdoc.api-docs.enabled=false

11.47. 如何隐藏响应的架构?

  • 要隐藏响应元素,请使用@Schema注释,如下所示,在操作级别:
@Operation(responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(hidden = true))))
  • 或直接在@ApiResponses级别:
@ApiResponses(value = {@ApiResponse(responseCode = "200", content = @Content(schema = @Schema(hidden = true))) }) 
OR 
@ApiResponse(responseCode = "404", description = "Not found",内容 = @Content)

11.48. swagger-ui当我设置不同的上下文路径时,的 URL 是什么?

  • 如果您使用不同的上下文路径:
server.servlet.context-path= /foo
  • swagger-ui将可在以下网址:
    • http://server:port/foo/swagger-ui.html

11.49. 我可以以编程方式自定义 OpenAPI 对象吗?

  • 您可以定义自己的 OpenAPI Bean:如果您需要定义全局显示(在每个组内),无论该组是否满足 GroupedOpenApi 上指定的条件,您都可以使用 OpenAPI Bean。
@Bean
public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) {
   return new OpenAPI()
    .components(new Components().addSecuritySchemes("basicScheme",
            new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic")))
    .info(new Info().title("SpringShop API").version(appVersion)
            .license(new License().name("Apache 2.0").url("http://springdoc.org")));
}
  • 如果您需要定义出现在特定组中,并遵守 GroupedOpenApi 上指定的条件,您可以将 OpenApiCustomiser 添加到您的 GroupedOpenApi 定义中。
GroupedOpenApi.builder().group("users").pathsToMatch(paths).packagesToScan(packagedToMatch).addOpenApiCustomiser(customerGlobalHeaderOpenApiCustomiser())
                .build()

@Bean
public OpenApiCustomiser customerGlobalHeaderOpenApiCustomiser() {
   return openApi -> openApi.path("/foo",
   new PathItem().get(new Operation().operationId("foo").responses(new ApiResponses()
   .addApiResponse("default",new ApiResponse().description("")
   .content(new Content().addMediaType("fatz", new MediaType()))))));
}

11.50。在哪里可以找到演示应用程序的源代码?

11.51。这个库是否支持来自接口的注释?

  • 是的

11.52。排除的参数类型列表是什么?

11.53。是否支持文件上传?

  • 该库支持主要文件类型:MultipartFile, @RequestPart,FilePart

11.54。我可以使用@Parameter内部@Operation注释吗?

  • 是的,支持

11.55。为什么我的参数被标记为required?

  • 任何@GetMapping参数都标记为必需,即使@RequestParam缺少。
  • @Parameter(required=false)如果您需要不同的行为,您可以添加注释。
  • defaultValue指定的查询参数标记为必填项。

11.56。具有相同端点但具有不同参数的重载方法如何

  • springdoc将这些方法呈现为单个端点。它检测过载的端点,并生成 parameters.schema.oneOf。

11.57。设置 Swagger UI 以使用提供的 spec.yml 的正确方法是什么?

  • 使用此属性,所有 springdoc-openapi 自动配置 bean 都被禁用:
springdoc.api-docs.enabled=false
  • 然后通过添加这个 Bean 来启用最小 bean 配置:
@Bean
SpringDocConfiguration springDocConfiguration(){
   return new SpringDocConfiguration();
}
@Bean
public SpringDocConfigProperties springDocConfigProperties() {
   return new SpringDocConfigProperties();
}
  • 然后配置自定义 UI yaml 文件的路径。
springdoc.swagger-ui.url=/api-docs.yaml

11.58。有没有办法通过@Parameter 标签发送授权标头?

11.59。我使用 @Controller 注释的 Rest Controller 被忽略了?

  • 如果您@Controller没有注释,这是默认行为@ResponseBody
  • 您可以将控制器更改为@RestControllers. 或添加@ResponseBody+ @Controller
  • 如果不可能,您可以配置 springdoc 以使用 SpringDocUtils 扫描您的其他控制器。例如:
static {
   SpringDocUtils.getConfig().addRestControllers(HelloController.class);
}

11.60。如何使用 application.yml 定义组?

  • 您可以使用 spring-boot 配置文件动态加载组。
  • 请注意,对于这种用法,您不必声明GroupedOpenApi Bean。
  • 您需要在前缀springdoc.group-configs下声明以下属性。
  • 例如:
springdoc.group-configs[0] 
.group =users springdoc.group-configs[0].paths-to-match=/user/** 
springdoc.group-configs[0].packages-to-scan=test.org .springdoc.api

11.61。如何从参数对象中提取字段?

  • 您可以使用 springdoc 注释@ParameterObject。
  • 使用@ParameterObject 注释的请求参数将有助于将参数的每个字段添加为单独的请求参数。
  • 这与映射到 POJO 对象的 Spring MVC 请求参数兼容。
  • 此注释不支持嵌套参数对象。

11.62。如何将 Open API 3 与 Spring 项目(不是 Spring Boot)集成?

当您的应用程序在不使用 (spring-boot) 的情况下使用 spring 时,您需要添加 spring-boot 中本机提供的 bean 和自动配置。

例如,假设您想在 spring-mvc 应用程序中加载 swagger-ui:

  • 您主要需要添加 springdoc-openapi 模块
<dependency>
   <groupId>org.springdoc</groupId>
   <artifactId>springdoc-openapi-ui</artifactId>
   <version>last.version</version>
</dependency>
  • 如果您没有 spring-boot 和 spring-boot-autoconfigure 依赖项,则需要添加它们。并注意 spring.version 和 spring-boot.version 之间的兼容性矩阵。例如,在这种情况下(spring.version=5.1.12.RELEASE):
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot</artifactId>
    <version>2.1.11.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
    <version>2.1.11.RELEASE</version>
</dependency>
  • 扫描 spring-boot 自动为你加载的 springdoc 自动配置类。
  • 根据您的模块,您可以在每个 springdoc-openapi 模块的文件 spring.factories 中找到它们。
@EnableWebMvc
public class AppInitializer implements WebApplicationInitializer {

   @Override
   public void onStartup(ServletContext servletContext) throws ServletException {
      WebApplicationContext context = getContext();
      servletContext.addListener(new ContextLoaderListener(context));
      ServletRegistration.Dynamic dispatcher = servletContext.addServlet("RestServlet",
            new DispatcherServlet(context));
      dispatcher.setLoadOnStartup(1);
      dispatcher.addMapping("/*");
   }

   private AnnotationConfigWebApplicationContext getContext() {
      AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
      context.scan("rest");
      context.register(this.getClass(), org.springdoc.ui.SwaggerConfig.class,
            org.springdoc.core.SwaggerUiConfigProperties.class, org.springdoc.core.SwaggerUiOAuthProperties.class,
            org.springdoc.webmvc.core.SpringDocWebMvcConfiguration.class,
            org.springdoc.webmvc.core.MultipleOpenApiSupportConfiguration.class,
            org.springdoc.core.SpringDocConfiguration.class, org.springdoc.core.SpringDocConfigProperties.class,
            org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration.class);

      return context;
   }
}

11.63。如何使用最后一个 springdoc-openapi SNAPSHOT ?

  • 仅用于测试目的,您可以使用最后一个 springdoc-openapi SNAPSHOT 临时测试
  • 为此,您可以在 pom.xml 或 settings.xml 中添加以下部分:
     <repositories>
       <repository>
         <id>snapshots-repo</id>
         <url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
         <releases><enabled>false</enabled></releases>
         <snapshots><enabled>true</enabled></snapshots>
       </repository>
     </repositories>

11.64。如何使用启用 springdoc-openapi MonetaryAmount 支持?

  • 如果应用程序想要启用 springdoc-openapi 支持,它声明:
SpringDocUtils.getConfig().replaceWithClass(MonetaryAmount.class, org.springdoc.core.converters.models.MonetaryAmount.class);
  • 另一种不使用 springdoc-openapi MonetaryAmount 的解决方案是:
SpringDocUtils.getConfig().replaceWithSchema(MonetaryAmount.class, new ObjectSchema()
            .addProperties("amount", new NumberSchema()).example(99.96)
            .addProperties("currency", new StringSchema().example("USD")));

11.65。如何在一个应用程序中聚合外部端点(公开 OPENAPI 3 规范)?

属性springdoc.swagger-ui.urls.*,适合配置外部(/v3/api-docs url)。例如,如果您想在一个应用程序中聚合其他服务的所有端点。重要提示:不要忘记还需要启用 CORS。

11.66。如何使用自定义 json/yml 文件而不是生成的文件?

如果您的文件 open-api.json 包含 OpenAPI 3 格式的 OpenAPI 文档。然后简单地声明:文件名可以是任何你想要的,从你声明的那一刻起就一致 yaml 或 json OpenAPI 规范。

   springdoc.swagger-ui.url=/open-api.json

然后文件open-api.json,应该位于:src/main/resources/static 不需要额外的配置。

11.67。如何启用 CSRF 支持?

如果您使用标准标头。(例如使用 spring-security 标头)如果需要 CSRF 令牌,swagger-ui 会在每个 HTTP REQUEST 期间自动发送新的 XSRF-TOKEN。

如果您的 XSRF-TOKEN 不是基于标准的,您可以使用 requestInterceptor 手动捕获最新的 xsrf 令牌并将其附加到通过 spring 资源转换器以编程方式的请求:

从 springdoc-openapi 的 v1.4.4 版本开始,添加了一个新属性以启用 CSRF 支持,同时使用标准头名称:

springdoc.swagger-ui.csrf.enabled=true

11.68。如何禁用默认的 swagger petstore URL?

您可以使用以下属性:

springdoc.swagger-ui.disable-swagger-default-url=true

11.69。是否支持 @PageableDefault 以增强 OpenAPI 3 文档?

是的,您可以将它与@ParameterObject注释结合使用 。此外,从 v1.4.5 开始支持spring-boot属性spring.data.web.spring.data.rest.default.

11.70。如何使 spring 安全登录端点可见?

您可以使用以下属性:

springdoc.show-login-endpoint=true

11.71。即使未引用架构,我如何显示架构定义?

您可以使用以下属性:

springdoc.remove-broken-reference-definitions=false

11.72。如何覆盖@Deprecated?

springdoc-openapi 的整个想法是让您的文档最接近代码,而代码更改最少。如果代码包含@Deprecated,sprindoc-openapi 也会将其架构视为已弃用。如果您想将 swagger 上的字段声明为不弃用,即使使用 java 代码,该字段也包含@Depreacted,您可以使用自 v1.4.3 版以来可用的以下属性:

springdoc.model-converters.deprecating-converter.enabled=false

11.73。如何显示返回 ModelAndView 的方法?

您可以使用以下属性:

springdoc.model-and-view-allowed=true

11.74。如何获得 OpenApi 规范的漂亮打印输出?

您可以使用以下属性:

springdoc.writer-with-default-pretty-printer=true

11.75。如何为同一个类定义不同的模式?

复杂对象总是被解析为对组件中定义的模式的引用。例如,让我们考虑一个PersonDTO类型为workAddressandhomeAddress属性的类Address

public class PersonDTO {

    @JsonProperty
    private String email;

    @JsonProperty
    private String firstName;

    @JsonProperty
    private String lastName;

    @Schema(ref = "WorkAddressSchema")
    @JsonProperty
    private Address workAddress;

    @Schema(ref = "HomeAddressSchema")
    @JsonProperty
    private Address homeAddress;

}

public class Address {

    @JsonProperty
    private String addressName;

}

如果你想为这个类定义两个不同的 schema,你可以设置 2 个不同的 schema,如下所示:

@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI().components(new Components()
.addSchemas("WorkAddressSchema", getSchemaWithDifferentDescription(Address.class, "work Address" ))
.addSchemas("HomeAddressSchema", getSchemaWithDifferentDescription(Address.class, "home Address" )));
}

private Schema getSchemaWithDifferentDescription(Class className, String description){
ResolvedSchema resolvedSchema = ModelConverters.getInstance()
.resolveAsResolvedSchema(
new AnnotatedType(className).resolveAsRef(false));
return resolvedSchema.schema.description(description);
}

11.76。如何根据使用情况为类属性定义不同的描述?

例如,让我们考虑一个PersonDTO具有email属性的类:

public class PersonDTO {

    @JsonProperty
    private String email;

    @JsonProperty
    private String firstName;

    @JsonProperty
    private String lastName;


}

如果你想为 定义两个不同的描述 email,你可以设置 2 个不同的模式,如下所示:

@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI().components(new Components()
.addSchemas("PersonDTO1", getFieldSchemaWithDifferentDescription(PersonDTO.class, "work email" ))
.addSchemas("PersonDTO2", getFieldSchemaWithDifferentDescription(PersonDTO.class, "home email" )));
}

private Schema getFieldSchemaWithDifferentDescription(Class className, String description){
    ResolvedSchema resolvedSchema = ModelConverters.getInstance()
            .resolveAsResolvedSchema(
                    new AnnotatedType(className).resolveAsRef(false));
    return resolvedSchema.schema.addProperties("email", new StringSchema().description(description));
}

11.77。什么是兼容性矩阵springdoc-openapispring-boot

springdoc-openapispring-boot 1和兼容spring-boot 2

一般来说,你应该只选择今天 1.6.2 的最后一个稳定版本。

更准确地说,这是针对其springdoc-openapi构建的 spring-boot 版本的详尽列表:

spring-boot 版本 最低 springdoc-openapi 版本
2.6.x, 1.5.x 1.6.0+
2.5.x, 1.5.x 1.5.9+
2.4.x, 1.5.x 1.5.0+
2.3.x, 1.5.x 1.4.0+
2.2.x, 1.5.x 1.2.1+
2.0.x, 1.5.x 1.0.0+

SwaggerHub文档

SwaggerHub 是一个协作平台,您可以在其中使用OpenAPI 规范定义 API ,并在 API 的整个生命周期中对其进行管理。SwaggerHub 是由开源 Swagger 工具背后的同一个人带给您的。它将核心 Swagger 工具(UI、编辑器、Codegen、Validator)集成到一个平台中,以帮助您协调 API 生命周期的整个工作流。

使用 SwaggerHub,您可以:

SwaggerHub 入门

SwaggerHub 是什么?

SwaggerHub 是一个在线平台,您可以在其中设计 REST API——无论是公共 API、内部私有 API 还是微服务。SwaggerHub 背后的核心原则是Design First, Code later 。也就是说,您首先要布置 API、其资源、操作和数据模型,一旦设计完成,您就可以实现业务逻辑。

API 定义以 OpenAPI 格式(以前称为 Swagger)编写。它们保存在 SwaggerHub 云中,可以与 GitHub 或 Amazon API Gateway 等外部系统同步。您还可以在 SwaggerHub 上与您的团队协作,并随着 API 的发展维护多个版本的 API。

什么是 OpenAPI?

OpenAPI 规范(以前称为 Swagger 规范)是 REST API 的一种 API 描述格式。它同样适用于设计新 API 和记录现有 API。OpenAPI 可让您描述整个 API,包括可用的端点、操作、请求和响应格式、支持的身份验证方法、支持联系人和其他信息。

OpenAPI 规范自最初发布以来经历了多个版本。SwaggerHub 支持 OpenAPI 3.0(最新版本)和 OpenAPI 2.0。

OpenAPI 定义可以用 YAML 或 JSON 编写。SwaggerHub Editor 使用 YAML,但您可以导入和下载 YAML 和 JSON。

示例 OpenAPI 3.0 规范(采用 YAML 格式)如下所示:

openapi: 3.0.0
info:
  title: Sample API
  version: '1.0'
servers:
  - url: https://api.example.com/v1
paths:
  /hello:
    get:
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: string

这种简单的格式是人类可读的、机器可读的和不言自明的。这也是 OpenAPI 在 API 开发人员中如此受欢迎的原因之一。

什么是 Swagger?

OpenAPI 规范的伟大之处在于有很多支持它的 API 开发工具。Swagger 就是一个例子,它是一组用于设计、构建、记录和使用 REST API 的开源工具。主要的 Swagger 工具包括:

  • Swagger Editor – 基于浏览器的编辑器,您可以在其中编写 OpenAPI 定义。
  • Swagger UI – 将 OpenAPI 定义呈现为交互式 API 文档,例如http://petstore.swagger.io 中的文档。
  • Swagger Codegen – 基于 OpenAPI 定义生成服务器代码和客户端库。

SwaggerHub 结合了这些工具以提供无缝体验,并在其上添加托管存储、访问控制和协作功能。

SwaggerHub 用户界面概述

当您登录 SwaggerHub 时, 我的中心页面列出了您有权访问的所有 API。这些既是您创建的 API,也是您被邀请合作开发的 API。如果您是 SwaggerHub 的新手并且还没有 API,则该列表将为空,但一旦您开始创建 API,它就会发生变化。

要在 SwaggerHub 上搜索现有 API,请使用可以通过单击访问的搜索页面在左侧边栏中。通过这种方式,您可以找到其他 SwaggerHub 用户开发的一些很棒的公共 API。有关搜索语法,请参阅搜索 SwaggerHub

要查看特定 API,请在列表中单击它。

SwaggerHub 上的 API 页面是一个拆分视图,显示您的 OpenAPI 定义的 YAML 代码以及从中生成的漂亮的参考样式 API 文档。API 文档允许用户直接在浏览器中测试 API 调用。左侧的导航面板显示了 API 中定义的操作和模型列表,让您可以跳转到 YAML 代码中的相应位置。您可以通过拖动面板之间的分隔线来调整面板的大小。

使用 SwaggerHub 创建示例 API

了解 SwaggerHub 的最佳方式是创建一个示例 API,让我们这样做。不要担心配置服务器。在本教程中,我们将专注于设计 API。

步骤 1. 创建 API

在左侧边栏中,单击 并选择创建新 API

填写API信息,如下图所示。

OpenAPI 版本指定了规范格式,OpenAPI 3.0.0 或 2.0。选择3.0.0(最新版本)。

有预定义的模板,例如Petstore,但是现在,让我们从一个空白的 API(无模板)开始。

输入示例作为 API 名称,1.0.0作为版本,示例 API作为标题和任意描述。

单击创建 API。SwaggerHub 编辑器将打开,其中预先填充了您输入的 API 元数据:

每个 API 定义都以 OpenAPI 版本开头,在我们的示例中是openapi: 3.0.0.

openapi: 3.0.0

下一部分info包含有关 API 的元数据——API 标题、描述、版本等。该info部分还可能包含联系信息、许可证和其他详细信息。

info:
  title: Sample API
  version: 1.0.0
  description: This is a sample API.

paths部分是您定义 API 操作的地方。我们稍后会填充它。

paths: {}

步骤 2. 添加服务器信息

接下来,我们需要定义 API 服务器地址和 API 调用的基本 URL。假设 API 将位于https://api.example.com/v1. 这可以描述为:

servers:
  - url: https://api.example.com/v1

info和之间添加这些行paths,如下所示:

步骤 3. 定义 GET 操作

假设我们的 API 旨在管理用户列表。每个用户都有一个 ID,API 需要一个操作以通过他们的 ID 返回用户。那将是一个像这样的 GET 请求:

GET /users/3
GET /users/15

使用 Swagger,我们可以将这个 GET 操作描述如下。的{userId}部分/users/{userId}表示路径参数,即,一个URL组件可以变化。

paths:
  /users/{userId}:
    get:
      summary: Returns a user by ID
      responses:
        '200':
          description: OK

将上面的代码粘贴到编辑器中,替换该paths: {}行。您的规范应如下所示:

请注意,在您编辑规范时,SwaggerHub 会自动更新右侧的预览。

步骤 4. 定义参数

我们的 API 操作GET /users/{userId}具有userId指定要返回的用户 ID的参数。要在您的规范中定义此参数,请添加以下parameter部分:

paths:
  /users/{userId}:
    get:
      summary: Returns a user by ID
      parameters:
        - name: userId
          in: path
          required: true
          description: The ID of the user to return
          schema:
            type: integer
      responses:
        '200':
          description: OK

此代码指定参数name(与 URL 路径中使用的参数相同)typedescription以及是否为requiredin: path表示参数作为 URL 路径的一部分 ( GET /users/15)传递,而不是例如查询字符串参数 ( GET /users?id=15)。

请注意,添加该parameters部分后,预览会更新以反映新添加的参数信息:

步骤 5. 定义响应

接下来,我们需要描述可能responses的 API 调用。响应由 HTTP 状态代码、描述和可选schema(响应主体的数据模型,如果有)定义。

假设成功调用GET /users/{userId}返回 HTTP 状态 200 和此 JSON 对象:

{
  "id": 42,
  "name": "Arthur Dent"
}

要描述此响应,请content在 200 响应下添加如下部分。该content部分指定响应包含 JSON 数据 ( application/json)。注意schema元素——它描述了响应主体的结构,例如返回的 JSON 对象的属性。

paths: 
  /users/{userId}:
    get:
      ...
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: integer
                  name:
                    type: string

您还可以描述 API 调用可以返回的各种错误代码:

      responses:
        ...
        '400':
          description: The specified user ID is invalid (e.g. not a number)
        '404':
          description: A user with the specified ID was not found

完整的规范现在应该是这样的:

步骤 6. 发布 API

我们的 API 已经完成,所以让我们发布它。发布是一种告诉人们 API 处于稳定状态的方式,它将按设计工作并准备好供应用程序使用。不要担心配置服务器——本教程是关于在没有实际实现的情况下设计 API 规范。

要发布 API,请单击您的 API 版本旁边的下拉箭头,然后单击

恭喜!您已经在 SwaggerHub 上发布了您的第一个 API!您可以从浏览器的地址栏中复制其地址并与他人共享。由于这是一个公共 API,任何有链接的人都可以查看它,它会显示在 SwaggerHub 的搜索结果中。如果您的 SwaggerHub 计划允许,您可以将 API设为私有

请注意,已发布的 API 将变为只读,并且只有在再次取消发布 API 时才能对其进行编辑。如果您需要改进description文本或修复拼写错误,可以暂时取消发布 API 。但是对于像新操作或参数这样的重大更改,您应该使用SwaggerHub 编辑器中的“添加版本”命令来启动一个新版本。SwaggerHub 允许您维护 API 规范的多个版本,因此您可以处理下一个 API 版本,同时保持已发布版本(“生产”版本)的完整性。

在 SwaggerHub 编辑器中要做的其他事情

SwaggerHub 编辑器不仅仅是一个编辑器,它还提供了用于管理 API 规范并将其集成到工作流中的工具。让我们快速浏览一下其他可用的命令:

  • 设置菜单可让您重命名 API、将其分叉或将其转移给其他所有者。
  • 导出”菜单可让您为 API生成服务器客户端代码,以帮助您开始实施。您还可以在此处将 OpenAPI 定义下载为 YAML 或 JSON。

SwaggerHub 上的协作

设计、开发和文档是发布优秀 API 不可或缺的一部分。在软件团队中,角色重叠,不同团队之间不断交换信息以构建完美的 API。我们将引导您完成创建和管理组织的指南,同时重点介绍如何在团队中使用 SwaggerHub 在 API 开发过程中进行迭代和审议。

定义组织和团队

SwaggerHub 协作功能的构建牢记现代团队的需求,以允许 API 的迭代和跨功能开发。这可以通过在 SwaggerHub 中定义组织和团队来实现。

要创建组织,请单击 新建在左侧边栏中,选择创建新组织。指定组织帐户名称(唯一 ID)、组织电子邮件和可选的Title

成功创建组织后,您可以将现有 SwaggerHub 用户添加为组织的成员。为此,请单击 组织页面右上角的 。

这将打开组织设置。切换到“成员”选项卡以邀请用户加入您的组织。

请记住,您的组织邀请将通过电子邮件发送给团队成员,由他们来接受邀请。例如,在下图中,Fernando ( fbmattos) 已接受组织邀请,而 Daria ( daria) 尚未接受。

组织的力量可以通过团队完全实现,该功能可以让组织所有者组成员共同处理 API。在任何组织中,您都可以在组织设置屏幕的团队选项卡上创建团队:

在我们的场景中,以下团队将开发 API:

  • API 架构师 – 负责 API 设计。
  • API 文档 - 负责记录 API。
  • API 开发——负责开发 API 的服务器端和客户端代码。

我们现在已经成功创建了一个组织,添加了成员并将他们添加到团队中。

在您的组织下创建 API

我们将介绍如何在组织下从头开始创建 API,但最好记住 API 也可以导入或分叉。

点击 ,选择创建新 API并从所有者列表中选择您的组织。如果您不熟悉在 SwaggerHub 上创建 API,请查看入门指南

不同的利益相关者管理 API 开发过程的不同部分。每个 API 都从了解需求开始。这是供公司内部使用以构建更好软件的私有 API,还是可用于推动市场发展并提高对公司产品和服务的认识的面向公众的 API?

根据产品所有者和技术负责人提出的要求,API 将确定对 API 的需求,无论是公共的还是私有的。SwaggerHub 允许所有者直接在SwaggerHub 编辑器中定义 API 的可见性:

私有 API 通常由技术主管和开发经理带头,他们认识到需要内部 API 来简化组织内其他应用程序的开发过程。产品负责人、营销经理和技术负责人通常会主导对大众开放的公共 API 的讨论。只有充分探索和设定 API 的愿景、目的和技术,API 设计和开发团队才能帮助其成为现实。

添加协作者

SwaggerHub 上的 API,无论是公共的还是私有的,都可以有多个与其关联的协作者。创建 API 后,组织所有者可以通过 SwaggerHub 编辑器将团队作为协作者添加到 API,并使用他们选择的权限。

协作者可以编辑 API 并通过评论与其他协作者交流。协作者可以被赋予编辑 API 的能力(编辑器)、对 API 定义的各个行进行评论(评论者)或仅仅具有查看 API 的能力(查看器)。使用评论来讨论想法或指出 SwaggerHub 编辑器中 API 定义特定行中的问题。

例如,API 架构师和 API 文档团队可以编辑 API 和添加注释。可以赋予开发团队添加评论的能力。讨论想法、提出问题并指出 API 定义中的问题。

通过版本控制迭代

软件团队发布其应用程序的新版本和更新版本。这些版本建立在先前版本的基础上,添加了新的更改或错误修复,无需重写现有代码或语法。SwaggerHub 的版本控制系统可以帮助解决这个问题。协作者可以定义每个 API 的多个版本,这意味着可以在多个版本中进行新的修订和编辑,而不会覆盖源。

添加新版本

协作者可以通过在 API 版本列表中单击添加新版本来添加新版本的 API:

所有合作者都将获得对新版本的即时访问,这使得继续处理 API 的多个更新变得非常简单。版本控制不仅对于跟踪修订很重要,而且对于保持最新的 API 概念和设计更新也很重要。

一旦团队对 API 设计感到满意,并且所有后端服务和文档都准备就绪,就可以发布 API。

通过发布最新版本,所有可以访问 API 的用户都知道该版本是稳定的,可以安全地引用和使用。发布 API 版本使其成为只读。但是,如果您需要对已发布的版本进行一些重要更改,您可以暂时取消发布它。

最后阶段

在您完成设计并发布 API 后,所有协作者都会收到通知并可以开始处理客户端 SDK 和后端服务。

SwaggerHub 支持生成服务器端模板和客户端 SDK,它负责处理所有样板代码,让开发人员可以完全专注于业务逻辑。

设计、后端服务和客户端 SDK 准备就绪后,剩下的就是部署和管理 API,可能使用 SwaggerHub 的 API 管理集成(如 Azure 或 AWS Gateway)。

使用组织、团队、成员角色、版本控制和评论的力量,SwaggerHub 为协作 API 开发提供了很好的体验。

OpenAPI 3.0 教程

OpenAPI 3.0 是 OpenAPI 规范的最新版本,这是一种用于描述和记录 API 的开源格式。在本教程中,我们将以 OpenAPI 3.0 格式编写一个简单的 API 定义。如果您使用的是 OpenAPI 2.0 (Swagger 2.0),请参阅本教程

什么是 OpenAPI?

OpenAPI 规范(以前称为 Swagger 规范)是一种用于描述和记录 API 的开源格式。该规范最初由 Reverb Technologies(原 Wordnik)于 2010 年开发,旨在使 API 设计和文档保持同步。它已成为设计和描述 RESTful API 的事实上的标准,并被数以百万计的开发人员和组织用于开发他们的 API,无论是内部的还是面向客户端的。

OpenAPI 的最新版本是3.0。OpenAPI 定义可以用 JSON 或 YAML 编写。我们推荐 YAML,因为它更易于阅读和编写。

一个简单的 OpenAPI 3.0 规范如下所示:

openapi: 3.0.0
info:
  version: 1.0.0
  title: Sample API
  description: A sample API to illustrate OpenAPI concepts
paths:
  /list:
    get:
      description: Returns a list of stuff              
      responses:
        '200':
          description: Successful response

一旦我们完成本演练,上面的语法就会有意义。

先决条件

  • RESTful API 的基础知识。
  • 推荐 YAML 基础知识。

我们建议使用 SwaggerHub 的内置编辑器和验证器来快速编写和可视化本教程中描述的 OpenAPI 定义。SwaggerHub 是免费的,具有大量功能,可让您快速入门,快来试试吧!

创建 API

我们将为唱片公司设计一个 API。让我们假设唱片公司有一个包含以下信息的艺术家数据库:

  • 艺人姓名
  • 艺术家类型
  • 在该标签下发布的专辑数量
  • 艺术家用户名

该 API 将让消费者获取存储在数据库中的艺术家列表并将新艺术家添加到数据库中。

使用 OpenAPI 规范定义的 API 可以分为 3 个主要部分 -

  • 元信息
  • 路径项(端点):
    • 参数
    • 请求主体
    • 回应
  • 可重用组件:
    • 模式(数据模型)
    • 参数
    • 回应
    • 其他组件

元信息

让我们从一个简单的 API 定义开始,它只包含元信息,例如 API 标题、版本、服务器 URL 和其他描述性信息。

openapi: 3.0.0
info:
  version: 1.0.0
  title: Simple Artist API
  description: A simple API to illustrate OpenAPI concepts

servers:
  - url: https://example.io/v1

# Basic authentication
components:
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
security:
  - BasicAuth: []

paths: {}

每个 API 定义都以该定义使用的 OpenAPI 规范的版本开始。在我们的示例中,它是openapi: 3.0.0。该info对象包含必需的 APItitleversion,以及可选的description.

servers数组为 API 调用指定了一个或多个服务器 URL。API 端点路径附加到服务器 URL。一些 API 有一个服务器,其他的可能有多个服务器,例如生产和沙箱。在我们的示例中,服务器 URL 是https://example.io/v1

我们还使用基本身份验证保护 API,以便只有授权用户才能使用 API。有关更高级的安全性,请参阅身份验证

路径项

路径项是您的 API 的端点,您可以在这些端点下指定 HTTP 动词以所需的方式操作资源。这些端点与服务器 URL 相关,在我们的示例中是https://example.io/v1.

我们将定义/artists端点和该端点的 GET 方法。因此,客户端将用于GET https://example.io/v1/artists获取艺术家列表。

openapi: 3.0.0
info:
  version: 1.0.0
  title: Simple API
  description: A simple API to illustrate OpenAPI concepts

servers:
  - url: https://example.io/v1

components:
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
security:
  - BasicAuth: []

#  ----- Added lines  ----------------------------------------
paths:
  /artists:
    get:
     description: Returns a list of artists 
#  ---- /Added lines  ----------------------------------------

回应

artists端点下的 GET 方法让 API 的使用者可以从 https://example.io/v1 数据库中获取艺术家列表的详细信息。

每个响应至少需要一个 HTTP 状态代码来描述消费者可能期望的响应类型。该描述详细说明了 API 的响应内容。在我们的示例代码中,我们指定了 200,这是一个成功的客户端请求,而 400 是一个不成功的请求。您可以在此处找到有关 HTTP 状态代码的更多信息。成功的响应将返回艺术家姓名、流派、用户名和录制的专辑。不成功的请求在 400 HTTP 代码下描述,并带有相应的错误消息,详细说明响应无效的原因。

openapi: 3.0.0
info:
  version: 1.0.0
  title: Simple API
  description: A simple API to illustrate OpenAPI concepts

servers:
  - url: https://example.io/v1

components:
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
security:
  - BasicAuth: []

paths:
  /artists:
    get:
      description: Returns a list of artists 
      #  ----- Added lines  ----------------------------------------
      responses:
        '200':
          description: Successfully returned a list of artists
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  required:
                    - username
                  properties:
                    artist_name:
                      type: string
                    artist_genre:
                      type: string
                    albums_recorded:
                      type: integer
                    username:
                      type: string

        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                properties:   
                  message:
                    type: string
      #  ---- /Added lines  ----------------------------------------

有关响应的更多信息,请参阅描述响应

参数

RESTful 参数指定用户使用的资源的可变部分。如果您想获得一些有关参数的高级信息,请参阅描述参数

查询参数

查询参数是最常见的参数类型。它们出现在 URL 末尾的问号后面。查询参数是可选的且非唯一的,因此可以在 URL 中多次指定它们。它是 URL 的非分层组件。

在我们的示例中,让客户端限制所需的信息而不是从数据库中返回整个艺术家列表是有意义的,这会导致服务器上不必要的负载。客户端可以描述页码(偏移量)和页面上的信息量(限制),例如:

GET https://example.io/v1/artists?limit=20&offset=3

这些变量parameters在 OpenAPI 定义中的对象下定义。因此,规范现在看起来如下

openapi: 3.0.0
info:
  version: 1.0.0
  title: Simple API
  description: A simple API to illustrate OpenAPI concepts

servers:
  - url: https://example.io/v1

components:
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
security:
  - BasicAuth: []

paths:
  /artists:
    get:
      description: Returns a list of artists 
      #  ----- Added lines  ----------------------------------------
      parameters:
        - name: limit
          in: query
          description: Limits the number of items on a page
          schema:
            type: integer
        - name: offset
          in: query
          description: Specifies the page number of the artists to be displayed
          schema:
            type: integer
      #  ---- /Added lines  ----------------------------------------         

      responses:
        '200':
          description: Successfully returned a list of artists
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  required:
                    - username
                  properties:
                    artist_name:
                      type: string
                    artist_genre:
                      type: string
                    albums_recorded:
                      type: integer
                    username:
                      type: string

        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                properties:   
                  message:
                    type: string
请求正文

POST、PUT 和 PATCH 请求通常包含请求正文。请求正文是通过使用requestBody对象定义的。对于此 API,让我们为用户添加将艺术家发布到我们的数据库的功能。这将在/artists资源下。

API 现在将如下所示:

openapi: 3.0.0
info:
  version: 1.0.0
  title: Simple API
  description: A simple API to illustrate OpenAPI concepts

servers:
  - url: https://example.io/v1

components:
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
security:
  - BasicAuth: []

paths:
  /artists:
    get:
      description: Returns a list of artists 
      parameters:
        - name: limit
          in: query
          description: Limits the number of items on a page
          schema:
            type: integer
        - name: offset
          in: query
          description: Specifies the page number of the artists to be displayed
          schema:
            type: integer
      responses:
        '200':
          description: Successfully returned a list of artists
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  required:
                    - username
                  properties:
                    artist_name:
                      type: string
                    artist_genre:
                      type: string
                    albums_recorded:
                      type: integer
                    username:
                      type: string
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                properties:   
                  message:
                    type: string

    #  ----- Added lines  ----------------------------------------
    post:
      description: Lets a user post a new artist
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object 
              required:
                - username
              properties:
                artist_name:
                  type: string
                artist_genre:
                  type: string
                albums_recorded:
                  type: integer
                username:
                  type: string

      responses:
        '200':
          description: Successfully created a new artist

        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                properties:   
                  message:
                    type: string
    #  ---- /Added lines  ----------------------------------------
路径参数

路径参数可用于隔离客户端正在使用的数据的特定组件,例如https://example.io/v1/artists/{username}。路径参数是 URL 分层组件的一部分,因此按顺序堆叠。

让我们创建一个新端点,它根据提供的用户名返回特定艺术家的信息。这里的路径参数将是username我们需要其信息的艺术家的。路径参数(username在这种情况下)必须parameters在方法下的对象中强制描述。

openapi: 3.0.0
info:
  version: 1.0.0
  title: Simple API
  description: A simple API to illustrate OpenAPI concepts

servers:
  - url: https://example.io/v1

components:
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
security:
  - BasicAuth: []

paths:
  /artists:
    get:
      description: Returns a list of artists 
      parameters:
        - name: limit
          in: query
          description: Limits the number of items on a page
          schema:
            type: integer
        - name: offset
          in: query
          description: Specifies the page number of the artists to be displayed
          schema:
            type: integer
      responses:
        '200':
          description: Successfully returned a list of artists
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  required:
                    - username
                  properties:
                    artist_name:
                      type: string
                    artist_genre:
                      type: string
                    albums_recorded:
                      type: integer
                    username:
                      type: string
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                properties:   
                  message:
                    type: string

    post:
      description: Lets a user post a new artist
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object 
              required:
                - username
              properties:
                artist_name:
                  type: string
                artist_genre:
                  type: string
                albums_recorded:
                  type: integer
                username:
                  type: string
      responses:
        '200':
          description: Successfully created a new artist
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                properties:   
                  message:
                    type: string

  #  ----- Added lines  ----------------------------------------
  /artists/{username}:
    get:
      description: Obtain information about an artist from his or her unique username
      parameters:
        - name: username
          in: path
          required: true
          schema:
            type: string

      responses:
        '200':
          description: Successfully returned an artist
          content:
            application/json:
              schema:
                type: object
                properties:
                  artist_name:
                    type: string
                  artist_genre:
                    type: string
                  albums_recorded:
                    type: integer

        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object 
                properties:           
                  message:
                    type: string
  #  ---- /Added lines  ----------------------------------------

在这里,我们已将 指定username为路径参数。需要注意的是,路径参数必须将 true 属性设置为所需参数,以使规范有效。

如果你一直坚持到这里,那么恭喜你!您刚刚为唱片公司设计了一个简单的 API!

可重用组件

我们刚刚描述的只是 2 个端点和 3 个动作。这是大约 130 行规范,随着 API 变大,规范只会变得更长。到目前为止,您可能会在规范中注意到的一件事是,我们有相同的艺术家模式(艺术家姓名、流派、用户名和发布的专辑),在各种 200 和 400 响应中重复。更大的 API 将涉及重写和重用许多相同的规范,因此编写更复杂的 API 将是一项乏味的任务。

OpenAPI 规范有一个解决方案——可重用组件,可在同一 API 中的多个端点之间使用。这些组件在全局components部分中定义,然后在各个端点中引用。该规范定义了各种类型的可重用组件:

  • 模式(数据模型)
  • 参数
  • 请求主体
  • 回应
  • 响应头
  • 例子
  • 链接
  • 回调

模式

schemas全局components部分的子部分可以包含 API 使用和返回的各种数据模型。下面是我们如何components用来存储 HTTP 200 OK 响应的架构。我们的 API 定义已经有components包含的部分securitySchemes,现在我们移到components底部并添加了schemas小节。

openapi: 3.0.0
info:
  version: 1.0.0
  title: Simple API
  description: A simple API to illustrate OpenAPI concepts

servers:
  - url: https://example.io/v1

security:
  - BasicAuth: []

paths:
  /artists:
    get:
      description: Returns a list of artists 
      parameters:
        - name: limit
          in: query
          description: Limits the number of items on a page
          schema:
            type: integer
        - name: offset
          in: query
          description: Specifies the page number of the artists to be displayed
          schema:
            type: integer
      responses:
        '200':
          description: Successfully returned a list of artists
          content:
            application/json:
              schema:
                type: array
                items:
                  #  ----- Added line  ----------------------------------------
                  $ref: '#/components/schemas/Artist'
                  #  ---- /Added line  ----------------------------------------
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                properties:   
                  message:
                    type: string

    post:
      description: Lets a user post a new artist
      requestBody:
        required: true
        content:
          application/json:
            schema:
              #  ----- Added line  ----------------------------------------
              $ref: '#/components/schemas/Artist'
              #  ---- /Added line  ----------------------------------------
      responses:
        '200':
          description: Successfully created a new artist
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                properties:   
                  message:
                    type: string

  /artists/{username}:
    get:
      description: Obtain information about an artist from his or her unique username
      parameters:
        - name: username
          in: path
          required: true
          schema:
            type: string

      responses:
        '200':
          description: Successfully returned an artist
          content:
            application/json:
              schema:
                type: object
                properties:
                  artist_name:
                    type: string
                  artist_genre:
                    type: string
                  albums_recorded:
                    type: integer

        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object 
                properties:           
                  message:
                    type: string

components:
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic

  #  ----- Added lines  ----------------------------------------                
  schemas:
    Artist:
      type: object
      required:
        - username
      properties:
        artist_name:
          type: string
        artist_genre:
            type: string
        albums_recorded:
            type: integer
        username:
            type: string
  #  ---- /Added lines  ----------------------------------------

规范不仅更短,而且在需要具有相同模式的新端点时,设计人员无需花时间编写该部分。有关更多信息,请参见此处components

参数和响应

components部分还有用于存储可重用参数和响应的小节。在下面的规范,我们定义了可重复使用的查询参数offsetlimit,然后在引用它们/artists的端点。我们还定义了一个可重用的400Error响应,然后我们从所有端点引用它。

openapi: 3.0.0
info:
  version: 1.0.0
  title: Simple API
  description: A simple API to illustrate OpenAPI concepts

servers:
  - url: https://example.io/v1

security:
  - BasicAuth: []

paths:
  /artists:
    get:
      description: Returns a list of artists 
      parameters:
        #  ----- Added line  ------------------------------------------
        - $ref: '#/components/parameters/PageLimit'
        - $ref: '#/components/parameters/PageOffset'
        #  ---- /Added line  ------------------------------------------
      responses:
        '200':
          description: Successfully returned a list of artists
          content:
            application/json:
              schema:
                type: array
                items:
                  #  ----- Added line  --------------------------------
                  $ref: '#/components/schemas/Artist'
                  #  ---- /Added line  --------------------------------
        '400':
          #  ----- Added line  ----------------------------------------
          $ref: '#/components/responses/400Error'
          #  ---- /Added line  ----------------------------------------

    post:
      description: Lets a user post a new artist
      requestBody:
        required: true
        content:
          application/json:
            schema:
              #  ----- Added line  ------------------------------------
              $ref: '#/components/schemas/Artist'
              #  ---- /Added line  ------------------------------------
      responses:
        '200':
          description: Successfully created a new artist
        '400':
          #  ----- Added line  ----------------------------------------
          $ref: '#/components/responses/400Error'
          #  ---- /Added line  ----------------------------------------    

  /artists/{username}:
    get:
      description: Obtain information about an artist from his or her unique username
      parameters:
        - name: username
          in: path
          required: true
          schema:
            type: string

      responses:
        '200':
          description: Successfully returned an artist
          content:
            application/json:
              schema:
                type: object
                properties:
                  artist_name:
                    type: string
                  artist_genre:
                    type: string
                  albums_recorded:
                    type: integer

        '400':
          #  ----- Added line  ----------------------------------------
          $ref: '#/components/responses/400Error'
          #  ---- /Added line  ----------------------------------------     

components:
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic

  schemas:
    Artist:
      type: object
      required:
        - username
      properties:
        artist_name:
          type: string
        artist_genre:
            type: string
        albums_recorded:
            type: integer
        username:
            type: string

  #  ----- Added lines  ----------------------------------------
  parameters:
    PageLimit:
      name: limit
      in: query
      description: Limits the number of items on a page
      schema:
        type: integer

    PageOffset:
      name: offset
      in: query
      description: Specifies the page number of the artists to be displayed
      schema:
        type: integer

  responses:
    400Error:
      description: Invalid request
      content:
        application/json:
          schema:
            type: object 
            properties:
              message:
                type: string
  #  ---- /Added lines  ----------------------------------------

要跳转到定义,只需单击$ref链接。

Swagger 2.0

什么是 Swagger?

Swagger 是一个用于设计和描述 API 的开源框架。Swagger 的旅程始于 2010 年,当时它由 Reverb Technologies(以前称为 Wordnik)开发,用于解决保持 API 设计和文档同步的需求。快进 6 年,Swagger 已成为设计和描述 RESTful API 的事实上的标准,数以百万计的开发人员和组织使用这些 API 来开发他们的 API,无论是内部的还是面向客户端的。

在本教程中,我们将以Swagger 2.0格式(也称为OpenAPI 2.0)编写 API 定义。Swagger 可以使用 JSON 或 YAML 编写,但我们建议使用 YAML 编写,因为它更易于阅读和理解。

一个简单的 Swagger 定义如下所示:

swagger: '2.0'
info:
  version: 1.0.0
  title: Simple example API
  description: An API to illustrate Swagger
paths:
  /list:
    get:
      description: Returns a list of stuff              
      responses:
        200:
          description: Successful response 

一旦我们完成本演练,上面的语法就会有意义。

为什么要Swagger?

有很多因素促使 Swagger 迅速采用构建 RESTful API。我们列出了为什么使用 Swagger 来设计 API 的最重要的一些:

  • 同时设计和记录 API,从而使蓝图和文档保持同步。
  • 人类和机器可读,自动生成交互式 API 文档以查看 API 的运行情况。
  • 围绕框架的大型综合工具生态系统,让您超越设计,从 SDK 生成到测试和调试。
  • 强大的开源社区支持和引领该框架。

创建 API

我们将为唱片公司设计一个 API。让我们假设唱片公司有一个包含以下信息的艺术家数据库:

  • 艺人姓名
  • 艺术家类型
  • 在该标签下发布的专辑数量
  • 艺术家用户名

该 API 将让消费者获取存储在数据库中的艺术家列表并将新艺术家添加到数据库中。

API 的 Swagger 定义可以分为 3 个不同的部分——

  • 元信息
  • 路径项目:
    • 参数
    • 回应
  • 可重用组件:
    • 定义
    • 参数
    • 回应

元信息

元信息部分是您可以提供有关整体 API 的信息的地方。可以在本节中定义 API 的作用、API 的基本 URL 是什么以及它遵循什么基于 Web 的协议等信息。

所有 Swagger 定义的 API 都以swagger: 2.0声明开头。然后使用其他必需的元数据(如版本和标题)指定信息对象。描述是可选的。

基本 URL 是任何应用程序或最终用户为了使用 API 将调用的。在这种情况下,它是https://example.io/v1,它是由限定schemeshostbasePath分别对象。

我们还可以添加一个仅允许授权用户使用 API 的基本身份验证。如需更高级的安全性,请参见此处

让我们从一个简单的元信息部分开始:

swagger: '2.0'
info:
  version: 1.0.0
  title: Simple Artist API
  description: A simple API to understand the Swagger Specification in greater detail

schemes:
- https
host: example.io
basePath: /v1

securityDefinitions:
  UserSecurity:
    type: basic

security:
  - UserSecurity: []

paths: {}

路径项

路径项是您的 API 的端点,您可以在这些端点下指定 HTTP 动词以所需的方式操作资源。这些端点相对于基本 URL(在我们的例子中是 http://example.io/v1)。在此示例中,我们列出/artists了 GET 方法所在的端点。

因此,客户端将使用GET http://example.io/v1/artists来获取艺术家列表。

swagger: '2.0'
info:
  version: 0.0.0
  title: Simple API
  description: A simple API to understand the Swagger Specification in greater detail

schemes: 
- https
host: example.io
basePath: /v1

securityDefinitions:
  UserSecurity:
    type: basic

security:
  - UserSecurity: [] 

#  ----- Added lines  ----------------------------------------
paths:
  /artists:
    get:
     description: Returns a list of artists 
#  ---- /Added lines  ----------------------------------------

回应

artists端点下的 GET 方法让 API 的使用者可以从 http://example.io/v1 数据库中获取艺术家列表的详细信息。

每个响应至少需要一个 HTTP 状态代码来描述消费者可能期望的响应类型。该描述详细说明了 API 的响应内容。在我们的示例代码中,我们指定了 200,这是一个成功的客户端请求,而 400 是一个不成功的请求。您可以在此处找到有关 HTTP 状态代码的更多信息。成功的响应将返回艺术家姓名、流派、用户名和录制的专辑。不成功的请求在 400 HTTP 代码下描述,并带有相应的错误消息,详细说明响应无效的原因。

swagger: '2.0'
info:
  version: 1.0.0
  title: Simple Artist API
  description: A simple API to understand the Swagger Specification in greater detail

schemes: 
- https

host: example.io
basePath: /v1

securityDefinitions:
  UserSecurity:
    type: basic

security:
  - UserSecurity: [] 

paths:
  /artists:
    get:
      description: Returns a list of artists 
      #  ----- Added lines  ----------------------------------------
      responses:
        200:
          description: Successfully returned a list of artists 
          schema:
            type: array
            items:
              type: object
              required:
               - username
              properties:
                artist_name:
                  type: string
                artist_genre:
                  type: string
                albums_recorded:
                  type: integer
                username:
                  type: string

        400:
          description: Invalid request 
          schema:
            type: object
            properties:   
              message:
                type: string
      #  ---- /Added lines  ----------------------------------------

有关响应的更多信息,请参见此处

参数

RESTful 参数指定用户使用的资源的可变部分。如果您想获得一些有关参数的高级信息,请阅读此处

查询参数

查询参数是最常见的参数类型。它们出现在 URL 末尾的问号后面。查询参数是可选的且非唯一的,因此可以在 URL 中多次指定它们。它是 URL 的非分层组件。

在我们的示例中,让客户端限制所需的信息而不是从数据库中返回整个艺术家列表是有意义的,这会导致服务器上不必要的负载。客户端可以描述页码(偏移量)和页面上的信息量(限制),例如:

GET http://example.com/v1/artists?limit=20&offset=3

这些变量parameters在 Swagger 定义中的对象下定义。因此,定义现在看起来如下——

swagger: '2.0'
info:
  version: 1.0.0
  title: Simple Artist API
  description: A simple API to understand the Swagger Specification in greater detail
schemes: 
- https
host: example.io
basePath: /v1
securityDefinitions:
  UserSecurity:
    type: basic
security:
  - UserSecurity: [] 
paths:
  /artists:
    get:
      description: Returns a list of artists 
      #  ----- Added lines  ----------------------------------------
      parameters:
        - name: limit
          in: query
          type: integer
          description: Limits the number of items on a page
        - name: offset
          in: query
          type: integer
          description: Specifies the page number of the artists to be displayed 
      #  ---- /Added lines  ----------------------------------------         

      responses:
        200:
          description: Successfully returned a list of artists 
          schema:
            type: array
            items:
              type: object
              required:
               - username
              properties:
                artist_name:
                  type: string
                artist_genre:
                  type: string
                albums_recorded:
                  type: integer
                username:
                  type: string

        400:
          description: Invalid request 
          schema:
            type: object
            properties:   
              message:
                type: string
机身参数

正文参数在请求正文中说明。这种参数的一个关键原则是在消息体中发送资源。正文参数非常适合 POST 和 PUT 请求。不建议在 GET 和 DELETE 操作中使用这些参数。

对于此 API,让我们为用户添加将艺术家发布到我们的数据库的功能。这将在/artists资源下。请注意包含在来自in:body描述的请求正文中指定的参数。

API 现在将如下所示:

swagger: '2.0'
info:
  version: 1.0.0
  title: Simple Artist API
  description: A simple API to understand the Swagger Specification in greater detail
schemes: 
- https
host: example.io
basePath: /v1
securityDefinitions:
  UserSecurity:
    type: basic
security:
  - UserSecurity: [] 
paths:
  /artists:
    get:
      description: Returns a list of artists 
      parameters:
        - name: limit
          in: query
          type: integer
          description: Limits the number of items on a page
        - name: offset
          in: query
          type: integer
          description: Specifies the page number of the artists to be displayed 


      responses:
        200:
          description: Successfully returned a list of artists 
          schema:
            type: array
            items:
              type: object
              required:
               - username
              properties:
                artist_name:
                  type: string
                artist_genre:
                  type: string
                albums_recorded:
                  type: integer
                username:
                  type: string

        400:
          description: Invalid request 
          schema:
            type: object
            properties:   
              message:
                type: string

    #  ----- Added lines  ----------------------------------------
    post:
      description: Lets a user post a new artist
      parameters:
        - name: artist
          in: body
          description: creates a new artist in our database
          schema:
            type: object 
            required:
              - username
            properties:
              artist_name:
                type: string
              artist_genre:
                type: string
              albums_recorded:
                type: integer
              username:
                type: string

      responses:
        200:
          description: Successfully created a new artist

        400:
          description: Invalid request 
          schema:
            type: object
            properties:   
              message:
                type: string
    #  ---- /Added lines  ----------------------------------------
路径参数

路径参数可用于隔离客户端正在使用的数据的特定组件,例如http://example.io/v1/{userrole}。路径参数是 URL 分层组件的一部分,因此按顺序堆叠。

让我们创建一个新端点,它根据提供的用户名返回特定艺术家的信息。这里的路径参数将是username我们需要其信息的艺术家的。路径参数(username在这种情况下)必须在方法下的参数对象中强制描述。

swagger: '2.0'
info:
  version: 1.0.0
  title: Simple Artist API
  description: A simple API to understand the Swagger Specification in greater detail
schemes: 
- https
host: example.io
basePath: /v1
securityDefinitions:
  UserSecurity:
    type: basic
security:
  - UserSecurity: [] 
paths:
  /artists:
    get:
      description: Returns a list of artists 
      parameters:
        - name: limit
          in: query
          type: integer
          description: Limits the number of items on a page
        - name: offset
          in: query
          type: integer
          description: Specifies the page number of the artists to be displayed 


      responses:
        200:
          description: Successfully returned a list of artists 
          schema:
            type: array
            items:
              type: object
              required:
               - username
              properties:
                artist_name:
                  type: string
                artist_genre:
                  type: string
                albums_recorded:
                  type: integer
                username:
                  type: string

        400:
          description: Invalid request 
          schema:
            type: object
            properties:   
              message:
                type: string

    post:
      description: Lets a user post a new artist
      parameters:
        - name: artist
          in: body
          description: creates a new artist in our database
          schema:
            type: object 
            required:
              - username
            properties:
              artist_name:
                type: string
              artist_genre:
                type: string
              albums_recorded:
                type: integer
              username:
                type: string

      responses:
        200:
          description: Successfully created a new artist

        400:
          description: Invalid request 
          schema:
            type: object
            properties:   
              message:
                type: string
  #  ----- Added lines  ----------------------------------------
  /artists/{username}:
    get:
      description: Obtain information about an artist from his or her unique username
      parameters:
        - name: username
          in: path 
          type: string
          required: true 

      responses:
        200:
          description: Successfully returned an artist
          schema:
            type: object
            properties:
              artist_name:
                type: string
              artist_genre:
                type: string
              albums_recorded:
                type: integer

        400:
          description: Invalid request
          schema:
            type: object 
            properties:           
              message:
                type: string
  #  ---- /Added lines  ----------------------------------------

在这里,我们已将 指定username为路径参数。需要注意的是,路径参数必须将 true 属性设置为所需参数,以使规范有效。

如果你一直坚持到这里,那么恭喜你!您刚刚为唱片公司设计了一个简单的 API!

可重用组件

我们刚刚描述的只是 2 个端点和 3 个动作。这是 83 行 API 定义,规范只会随着 API 变大而变长。到目前为止,您可能会在规范中注意到的一件事是,我们有相同的艺术家模式(艺术家姓名、流派、用户名和发布的专辑),在各种 200 和 400 响应中重复。更大的 API 将涉及重写和重用许多相同的规范,因此编写更复杂的 API 将是一项乏味的任务。

Swagger 规范有一个解决方案——定义可重用的组件。这些组件可以在同一 API 中的多个端点、参数和响应之间重复使用。

API 定义中有 3 种不同类型的可重用组件:

  • 定义
  • 回应
  • 参数

路径项也可以在 SwaggerHub 等应用程序的帮助下重用,这些应用程序存储可跨多个 API 引用的可重用组件。

定义

全局definitions部分可以包含 API 使用和返回的各种数据模型。以下是我们如何使用定义来存储 HTTP 200 OK 响应的架构:

swagger: '2.0'
info:
  version: 1.0.0
  title: Simple Artist API
  description: A simple API to understand the Swagger Specification in greater detail
schemes: 
- https
host: example.io
basePath: /v1
securityDefinitions:
  UserSecurity:
    type: basic
security:
  - UserSecurity: [] 
paths:
  /artists:
    get:
      description: Returns a list of artists 
      parameters:
        - name: limit
          in: query
          type: integer
          description: Limits the number of items on a page
        - name: offset
          in: query
          type: integer
          description: Specifies the page number of the artists to be displayed 


      responses:
        200:
          description: Successfully returned a list of artists 
          schema:
            type: array
            items:
              #  ----- Added line  ----------------------------------------
              $ref: '#/definitions/Artist'
              #  ---- /Added line  ----------------------------------------

        400:
          description: Invalid request 
          schema:
            type: object
            properties:   
              message:
                type: string

    post:
      description: Lets a user post a new artist
      parameters:
        - name: artist
          in: body
          description: creates a new artist in our database
          schema:
            #  ----- Added line  ----------------------------------------
            $ref: '#/definitions/Artist'
            #  ---- /Added line  ----------------------------------------

      responses:
        200:
          description: Successfully created a new artist

        400:
          description: Invalid request 
          schema:
            type: object
            properties:   
              message:
                type: string

  /artists/{username}:
    get:
      description: Obtain information about an artist from his or her unique username
      parameters:
        - name: username
          in: path 
          type: string
          required: true 

      responses:
        200:
          description: Successfully returned an artist
          schema:
            type: object
            properties:
              artist_name:
                type: string
              artist_genre:
                type: string
              albums_recorded:
                type: integer

        400:
          description: Invalid request
          schema:
            type: object 
            properties:           
              message:
                type: string

#  ----- Added lines  ----------------------------------------                
definitions:
  Artist:
    type: object
    required:
      - username
    properties:
      artist_name:
        type: string
      artist_genre:
          type: string
      albums_recorded:
          type: integer
      username:
          type: string
#  ---- /Added lines  ----------------------------------------

规范不仅更短,而且在需要具有相同模式的新端点时,设计人员无需花时间编写该部分。有关定义的更多信息,请参见此处

要跳转到对象定义,只需单击$ref链接。

参数和响应

我们还可以在可重用组件下定义一个单独的部分,用于存储可以在同一 API 中跨多个端点引用的参数和响应。

在下面的 API 定义中,我们在可重用参数下有PageLimitPageNumber参数,它们定义了我们在/artists端点下使用的查询参数。它们在 /artists 端点下引用。

我们还400Error定义了一个可重用的响应,它指定了我们在所有端点下使用的 400 响应,然后适当地引用它们。

swagger: '2.0'
info:
  version: 1.0.0
  title: Simple Artist API
  description: A simple API to understand the Swagger Specification in greater detail
schemes: 
- https
host: example.io
basePath: /v1
securityDefinitions:
  UserSecurity:
    type: basic
security:
  - UserSecurity: [] 
paths:
  /artists:
    get:
      description: Returns a list of artists 
      parameters:
        - $ref: '#/parameters/PageLimit'
        - $ref: '#/parameters/PageNumber'

      responses:
        200:
          description: Successfully returned a list of artists 
          schema:
            type: array
            items:
              $ref: '#/definitions/Artist'

        400:
          #  ----- Added line  ----------------------------------------
          $ref: '#/responses/400Error'
          #  ---- /Added line  ----------------------------------------

    post:
      description: Lets a user post a new artist
      parameters:
        - name: artist
          in: body
          description: creates a new artist in our database
          schema:
            $ref: '#/definitions/Artist'

      responses:
        200:
          description: Successfully created a new artist

        400:
          #  ----- Added line  ----------------------------------------
          $ref: '#/responses/400Error'
          #  ---- /Added line  ----------------------------------------

  /artists/{username}:
    get:
      description: Obtain information about an artist from his or her unique username
      parameters:
        - name: username
          in: path 
          type: string
          required: true 

      responses:
        200:
          description: Successfully returned an artist
          schema:
            type: object
            properties:
              artist_name:
                type: string
              artist_genre:
                type: string
              albums_recorded:
                type: integer

        400:
          #  ----- Added line  ----------------------------------------
          $ref: '#/responses/400Error'
          #  ---- /Added line  ----------------------------------------                

definitions:
  Artist:
    type: object
    required:
      - username
    properties:
      artist_name:
        type: string
      artist_genre:
          type: string
      albums_recorded:
          type: integer
      username:
          type: string
#  ----- Added lines  ----------------------------------------
parameters:
  PageLimit:
    name: limit
    in: query
    type: integer
    description: Limits the number of items on a page

  PageNumber:
    name: offset
    in: query
    type: integer
    description: Specifies the page number of the artists to be displayed
responses:
  400Error:
    description: Invalid request
    schema:
      type: object 
      properties:
        message:
          type: string
#  ---- /Added lines  ----------------------------------------

SwaggerHub UI

SwaggerHub 用户界面概述

SwaggerHub 允许您创建、编辑和托管 OpenAPI 定义,与您的团队协作处理它们并将它们与第三方服务集成。

匿名用户可以浏览和搜索公共 API 目录。登录用户还可以查看私有 API 以及创建和编辑 API 定义。

SwaggerHub API 浏览器

当您登录 SwaggerHub 时,您会看到您有权访问的所有 API——公共和私有的、由您创建并与您共享。如果您是 SwaggerHub 的新手并且还没有 API,则该列表将为空,但一旦您开始创建 API,它就会发生变化。

API 和域

SwaggerHub 上有两种类型的定义——API 和域。是共享部件,例如,可以在不同的API使用模型定义和操作参数的集合。API 和域在列表中具有相应的标签。

公开、私有、已发布和未发布

所有定义都标记为PublicPrivate,以及PublishedUnpublished。这些术语的含义不同:

  • PublicPrivate表示可见性。任何人都可以看到公开定义,私有定义仅对选定的合作者可见。请参阅公共和私有 API
  • 已发布未发布表示成熟度或完整性。未发布的定义正在进行中,已发布的定义不应更改并已准备好使用。请参阅发布 API

侧边栏

左侧的边栏允许您更改显示项目的范围:

我的中心 – 显示您有权访问的所有公共和私人定义,无论是由您创建还是与您共享。

搜索 – 在 SwaggerHub 上搜索所有定义。搜索包括您有权访问的公共定义和私有定义。

侧边栏还列出了您所属的所有组织项目。选择一个组织或项目以查看其定义。

为方便起见,侧边栏可以展开或折叠。

与API列表交互

  • 单击 API 或域标题将其打开。
  • 单击所有者名称(在最左侧的列中)以按该所有者过滤定义。
  • 对显示的定义进行排序和过滤,或使用相应的搜索过滤器
  • 单击 以复制指向 API 或域的链接。如果您是所有者,则显示的对话框还允许您邀请协作者加入此 API 或域。
  • 单击行上的任意位置以打开“详细信息”窗格。详细信息包括完整说明、创建日期和上次更新日期。

创建 API

使用 创建新菜单以创建新的 API、域和组织。

组织

边栏中的组织部分列出了您创建或加入的所有组织。组织是一起处理 API 定义的用户组。一个用户可以是多个组织的成员。

单击一个组织以查看您有权访问的所有 API 和域。如果您是组织所有者,则可以通过单击访问组织设置 在侧边栏中的组织名称旁边。

搜索

您通过单击访问的搜索页面左侧边栏中的 可让您在 SwaggerHub 上的数千个 API 和域中进行搜索。在我的枢纽和组织的网页也有一个搜索栏,你必须与组织的定义中访问的定义中进行搜索,分别。

设置

您用户名下的菜单可让您访问您的帐户设置。您可以使用它来更改您的电子邮件或密码、查看或更改您的计划、重命名您的帐户、管理您的组织等。

SwaggerHub Editor

SwaggerHub 允许您直接在浏览器中编写 API 定义并实时预览生成的 API 文档。

此外,您可以使用 Visual Studio Code 的 SwaggerHub 扩展,您可以在其中创建、编辑和验证 API 定义和域。该扩展与 SwaggerHub 同步,您所做的所有更改都会自动推送到它。在Visual Studio Marketplace 中了解有关 SwaggerHub 扩展的更多信息。

SwaggerHub 支持OpenAPI 2.0OpenAPI 3.0(有一些限制)。API 定义以YAML格式存储。您可以导入或粘贴 JSON,它将被转换为 YAML。请注意,您可以下载YAML 和 JSON 两种格式的OpenAPI 定义

概述

SwaggerHub 编辑器是一个拆分视图,左侧是编辑器,右侧是交互式 API 文档。编辑器有两种模式:

  • 代码编辑器可让您编辑 API 定义的 YAML 代码。该编辑器支持 OpenAPI 关键字的自动补全、语法高亮、搜索和替换操作、代码折叠和键盘快捷键
  • 可视化编辑器让您无需了解 OpenAPI 语法即可编辑 API 元数据和操作元数据。

您可以使用左侧边栏中的按钮在代码编辑器和可视化编辑器之间切换。编辑器每 2 分钟自动保存一次草稿,您也可以随时手动保存进度。

交互式 API 文档根据您的 API 定义生成并基于 Swagger UI。API 文档会在您键入时自动更新,帮助您可视化您正在创建的 API。在这里,您还可以直接在浏览器中进行 API 调用

左侧的导航面板显示 API 中定义的操作和模型列表。您可以通过路径、HTTP 动词和模型名称进行搜索和过滤,并快速导航到 YAML 代码中的相应位置。

您可以使用左侧的按钮隐藏或显示单个面板。

要撤消编辑器中任何未保存的更改,请使用“恢复到上次保存”命令。

语法验证

在您键入时,SwaggerHub 会自动验证您的 API 定义并显示可能发生的任何错误或警告,例如语法错误、未解析的引用或未使用的定义。要查看错误列表,请展开编辑器底部的验证栏。单击错误消息可跳转到触发此错误的行。

如果您的组织使用API 标准化,API 编辑人员可以在此处查看当前 API 中发现的样式违规。

信息面板:管理 API 和集成

单击标题区域中的 API 名称以打开 API 信息面板,您可以在其中重命名、比较或传输 API。注意:可用的命令取决于您是 API 所有者还是合作者

在信息面板的集成选项卡上,您可以为 API配置集成

在面板底部,您可以看到此 API 版本的创建者、创建时间、API 的所有者以及上次保存的日期和时间。

版本选择器

如果您的 API 有多个版本,您可以使用版本号旁边的下拉菜单在版本之间快速切换。

编辑器选项

您可以更改编辑器字体大小并在深色和浅色语法高亮主题之间切换。编辑器选项在当前浏览器的会话中持续存在。

链接

API 定义可以包括$ref对当前定义中的或组件的引用。要导航到引用的资源,请将鼠标悬停在该$ref值上并单击Jump To。外部链接在新的浏览器选项卡中打开。

各种各样的

编辑器的工具栏还包含以下项目:

同步管理

如果为当前 API 配置了源代码控制集成,请单击此按钮生成代码并将其推送到连接的存储库分支。

查看文档

单击以在新的浏览器选项卡中查看此 API 或域的交互式文档

API/域选项
  • 编辑 GitHub 推送 – 旧版 GitHub 集成。请改用GitHub 同步
  • 重置更改 - 撤消编辑器中所有未保存的更改。
启用/禁用通知

单击以订阅或取消订阅有关此 API 或域更改的电子邮件通知

分享与合作

单击以邀请其他用户在此 API 上进行协作

出口
  • 代码生成选项 – 在这里,您可以更改服务器存根和客户端 SDK的代码生成选项
  • 客户端 SDK –使用所选语言为此 API生成客户端 SDK
  • 服务器存根 -使用所选语言为此 API生成服务器存根
  • 文档 - 以所选格式为此 API 生成文档。
  • 下载 API下载域 – 让您以 YAML 或 JSON 格式下载 API 或域定义。

键盘快捷键

SwaggerHub 编辑器支持键盘快捷键以加快编辑速度。

查找/替换

行动 视窗/Linux 苹果电脑
查找对话框 Ctrl + F 命令 + F
替换对话框 Ctrl + H 命令 + 选项 + F
找下一个 Ctrl + K 命令 + G
查找上一个 Ctrl + Shift + K 命令 + Shift + G
查找光标下单词的所有实例(不区分大小写) Ctrl + Alt + K Ctrl + 选项 + G

编辑

行动 视窗/Linux 苹果电脑
显示自动完成列表 Ctrl + 空格 选项 + 空格
注释或取消注释当前行 Ctrl + / 命令 + /
删除当前行 Ctrl + D 命令 + D
撤消 Ctrl + Z 命令 + Z
重做 Ctrl + Y、Ctrl + Shift + Z 命令 + Y,命令 + Shift + Z
缩进选择 标签 标签
缩进选择 Shift + Tab Shift + Tab
全选 Ctrl + A 命令 + A

导航

行动 视窗/Linux 苹果电脑
转到行号 Ctrl + L 命令 + L
转到下一个错误 Alt + E
转到上一个错误 Alt + Shift + E

代码折叠

行动 视窗/Linux 苹果电脑
全部折叠 Alt + 0 命令 + 选项 + 0
展开全部 Alt + Shift + 0 命令 + 选项 + Shift + 0
折叠选择 Alt + L、Ctrl + F1 命令 + 选项 + L,命令 + F1
展开选择 Alt + Shift + L、Ctrl + Shift + F1 Command + Option + Shift + L、Command + Shift + F1
切换折叠 F2 F2

OpenAPI 定义的可视化编辑器

概述

使用可视化编辑器,您可以:

  • 编辑 API 信息:标题、描述、许可、联系信息、外部文档链接。
  • 编辑操作元数据:摘要、描述、标签。
  • 在 OpenAPI 3.0 定义中编辑服务器和服务器变量。
  • 删除操作。
  • 管理标签和编辑标签元数据。
  • 添加和删除模型。
  • 编辑模型描述(仅适用于definitionscomponents/schemas部分中的模型)。

目前不支持域编辑和上面未列出的其他功能。

打开可视化编辑器

要切换到可视化编辑器,请单击SwaggerHub 编辑器侧栏中的 显示可视化编辑器。如果光标位于 YAML 代码中的特定操作或模型内,则可视化编辑器将为该操作或模型打开。

如果定义包含 YAML 错误,则无法切换到可视化编辑器。使用 代码编辑器修复错误,然后重试。

用法

要选择要编辑的项目:

  • 在左侧的导航面板中选择一个项目。如果导航面板img处于隐藏状态,请单击侧边栏中的以显示它。

- 或者 -

  • 点击 操作预览或模型预览中的箭头。

    img

当您进行更改时,API 文档预览会自动更新以反映更改。编辑器每 2 分钟自动保存一次草稿,您也可以随时手动保存进度。已修改和未保存的项目在导航面板中用点 ( • ) 表示。

要撤消编辑器中任何未保存的更改,请使用“恢复到上次保存”命令。

“恢复到上次保存”命令

编辑API信息

点击信息中的导航面板编辑APIinfo部分,包括:

  • 一般信息:API 标题、描述和服务条款 URL
    • 版本字段是只读的。要更改 API 版本,请使用版本列表中的添加新版本命令。有关详细信息,请参阅版本控制
  • 联系信息:联系人姓名、电子邮件和 URL
  • 许可证信息:许可证名称和 URL
  • 外部文档的 URL 和描述

编辑操作元数据

使用可视化编辑器快速编辑摘要、描述并将标签添加到 API 中的现有操作。

编辑模型描述

导航面板中选择一个模型(模式)以编辑模型描述。模型描述支持富文本格式。

管理标签

标签用于将操作分组到 API 文档中的类别中。您可以直接将标签添加到操作中,而无需使用标签编辑器。但是,如果要为标签添加描述和文档链接,则必须在标签编辑器中明确定义这些标签。标签编辑器对应于 OpenAPI 定义中的全局标签部分。

点击标签导航面板访问标记编辑器。

OpenAPI 允许您直接在操作中定义标签。这些标签出现在 API 文档中,但不会出现在标签编辑器中,除非您直接创建它们。

要创建新标签,请单击 +.

要编辑标签元数据,请将鼠标悬停在标签上并单击 🖊.

要重新排列标签,请单击并拖动图标。这将更改 API 文档中的标签显示顺序。

要删除全局标签定义,请将鼠标悬停在标签上并单击 垃圾箱图标.

交互式 API 文档

SwaggerHub 为您的 OpenAPI 定义生成交互式 API 文档。使用它来探索 API 端点、参数、响应和数据模型,并直接在浏览器中测试 API 调用。

仅文档视图

单击 SwaggerHub 工具栏可仅查看 API 文档(或域文档)而无需编辑器。

复制生成的文档链接并与需要访问您的 API 文档的 API 使用者共享。

API 文档页面遵循与 API 和域页面相同的命名格式,但在地址中-docs添加/apis(或/domains)后缀:

https://app.swaggerhub.com/apis-docs/{owner}/{name}/{version}
                                 ^
https://app.swaggerhub.com/domains-docs/{owner}/{name}/{version}
                                    ^

如果省略版本号,文档页面将显示默认版本

https://app.swaggerhub.com/apis-docs/swagger-hub/registry-api

定制品牌

此信息仅适用于 SwaggerHub SaaS。

组织可以在其 API 文档中添加自定义徽标,以维护公司的品牌知名度。该徽标将显示在面向消费者的所有组织 API 和域的文档中。有关详细信息,请参阅文档品牌化

“试试看”

交互式文档让您可以使用Try it out按钮直接从浏览器测试 API 调用。SwaggerHub 将显示响应标头和正文、请求持续时间以及可用于从命令行发送相同请求的 cURL 命令。

请求的目标服务器

为了“试用”工作,您的 API 定义必须指定host(在 OpenAPI 2.0 中)或servers(在 OpenAPI 3.0 中),以便 SwaggerHub 知道将请求发送到哪里:

swagger: '2.0'
host: myapi.com
schemes:
  - https
basePath: /v2

# or

openapi: 3.0.0
servers:
  - url: 'https://myapi.com/v2'

如果您不想使用生产服务器,或者您还没有,您可以使用 SwaggerHub 的模拟服务器。模拟服务器将根据 API 定义中指定的响应模式和示例生成响应。

路由请求

SwaggerHub 允许您直接从浏览器向目标服务器发送“试用”请求,或通过 SwaggerHub 服务器代理请求。根据经验,使用浏览器访问本地 API,并使用代理访问面向 Internet 的 API。

您可以在文档底部更改路由模式。所选选项保存在浏览器中,localStorage并适用于您从该浏览器测试的所有 API。

通过 SwaggerHub 代理路由请求(默认)

这是面向 Internet 的 API 的首选模式。来自浏览器的“试用”请求首先发送到 SwaggerHub 服务器,后者将请求转发到目标 API 服务器。来自 API 服务器的响应被发送回 SwaggerHub 服务器,然后发送到您的浏览器。这种方法避免了浏览器对跨域 HTTP 请求的限制。

好处:

  • API 服务器上不需要 CORS 支持。
  • 支持Cookie标题中的用户定义参数。

要求:

  • 如果您使用 SwaggerHub SaaS,则 API 服务器必须位于公共 Internet 上并允许来自我们 IP 地址的连接。SwaggerHub On-Premise 支持面向 Internet 的服务器和本地服务器(除了localhost127.*.*.*172.18.*.*)。

限制:

  • 请求超时不可配置,设置为:
    • SwaggerHub SaaS 中的 30 秒
    • SwaggerHub On-Premise 1.21.0 及更高版本中的 30 秒
    • 在早期版本的 SwaggerHub On-Premise 中为 10 秒
  • 使用 SwaggerHub SaaS 时,“试用”请求通过 SwaggerHub 云服务器进行代理。如果担心基础设施的隐私或所有权,请改用通过浏览器的路由,或考虑使用托管在您自己的基础设施上的 SwaggerHub On-Premise。
  • 在 SwaggerHub On-Premise 中,请求不能发送到localhost127.*.*.*172.18.*.*

通过浏览器路由请求

在 SwaggerHub SaaS 和 SwaggerHub On-Premise 1.18.7 及更高版本中受支持。

在这种模式下,“试用”请求通过使用 JavaScript 从网页直接发送到 API 服务器。

好处:

  • 支持面向 Internet 的服务器和本地服务器。
  • 请求直接从您的浏览器发送到 API 服务器,无需通过任何中间基础设施。
  • 请求与浏览器 cookie 一起发送(但不使用用户定义的 cookie 参数)。

要求:

限制:

  • 无法从托管在 HTTPS 上的 SwaggerHub SaaS 和 SwaggerHub On-Premise 向 HTTP(非安全)服务器发送请求,因为浏览器会阻止从安全网页访问不安全的内容。
  • 无法在Cookie标头和其他禁止的请求标头中发送用户定义的值。
  • “试用”后显示的Access-Control-Expose-Headers响应头受响应头限制。如果缺少此标头,则仅显示简单的响应标头
  • Set-Cookie响应头不显示,由于浏览器的安全限制。

对“试用”请求进行故障排除

类型错误:无法获取

通过浏览器路由请求时,在以下情况下会发生此错误:

  • API 服务器不支持 CORS
  • 请求从https://网页发送到http://(非安全)服务器。

为避免此问题,请将路由模式更改为Use proxy

OpenAPI 3.0 细节

交互式文档目前不支持 OpenAPI 3.0 的某些功能。请参阅此处了解已知限制。

延迟加载

SwaggerHub 通过仅在渲染需要时加载外部引用来减少文档加载时间。请参阅延迟加载以了解更多信息。

永久链接

API 和域文档支持单个操作、标签、模型和域组件的永久链接。要获得特定项目的永久链接,请展开该项目,然后从浏览器地址栏中复制完整链接:

当用户导航到固定链接时,页面会自动滚动到目标项目并展开它。自己试试:

https://app.swaggerhub.com/apis-docs/swagger-hub/registry-api/1.0.47#/APIs/searchApisAndDomains

永久链接具有以下语法:

  • 对于标签和操作:

    ...#/TagName
    ...#/TagName/operationId
  • 对于其他项目:

    ...#/ItemType
    ...#/ItemType/ItemName

看看下面的一些例子:

例子 描述
...#/pet 链接到pet标签。
...#/pet/updatePet 链接到标签updatePet内带有 ID 的操作pet
...#/models/Order 链接到Order模型。
...#/parameters/limitParam 链接到limitParamOpenAPI 2.0 域中的参数定义。
...#/components/parameters/limitParam 链接到limitParamOpenAPI 3.0 域中的参数定义。

Searching SwaggerHub

使用SwaggerHub 搜索按名称、内容、状态或其他属性查找 API 和。匿名用户可以在所有公共定义中进行搜索。登录用户还可以在他们有权访问的私有定义中进行搜索。

我的中心,组织页面和项目页面也有一个搜索栏,搜索范围相应地受到限制。

文字搜索

搜索词不区分大小写并匹配:

  • API 定义和域的 YAML 内容,
  • info.titleinfo.description在定义上,
  • API和域名,
  • 所有者名称。

SwaggerHub 使用全文搜索。搜索查询的工作方式如下:

  • 包含多个术语的查询,例如在pet store定义的任何位置查找包含所有这些术语的定义。这等效于使用布尔 AND 运算符:pet AND store
  • 每个术语都作为子字符串匹配。例如,book会查找bookeBookbookstorebooking等。
  • 停用词和长度少于 3 个字符的词将被忽略。例如,搜索字符串get a report转换为report:单词“get”作为停用词被忽略,而“a”由于其长度而被忽略。
  • 字符+ - |被剥离——在索引期间和搜索时。所有其他字符都是可搜索的。例如:
    • 111222, 111-222, 11+12+22,11122|2被认为是同一个字符串。这些搜索字符串中的任何一个都可以找到所有这些字符串。
    • 搜索字符串/users/{id}将找到此文字字符串。
  • 不支持使用引号的短语搜索(例如“酒店预订”)。引号没有特殊含义,被视为常规单词字符。
  • 括号 ( ) 不影响布尔表达式的优先级。括号被视为常规单词字符。

布尔运算符

您可以使用布尔运算符组合搜索词来扩大或缩小搜索范围。这些运算符必须是大写的

AND(默认)

在任何地方查找包含这两个术语的定义。

或者

查找包含任一术语的定义。

不是

排除包含 NOT 之后的术语的定义。

例子:

过滤关键字

搜索查询可以包含以下关键字来过滤搜索结果。

类型:api

仅查找 API。

类型:域

仅查找

规格:openapi3.0

查找 OpenAPI 3.0 定义。

规格:swagger2.0

查找 OpenAPI 2.0 定义。

所有者:姓名

查找指定用户或组织拥有的 API 和域。所有者名称区分大小写。

可见性:公开

查找公共 API 和域。

可见性:私人

查找您拥有或与您共享的私人定义。您必须登录才能使用此选项。

状态:已发布

仅查找已发布的定义。

状态:未发表

仅查找未发布的定义。

标准化:失败

查找带有标准化错误或警告的API 。

标准化:关键

查找存在标准化错误的 API。

标准化:警告

查找带有标准化警告的 API。

注意SwaggerHub内部部署用户: standardization:criticalstandardization:warning因为V 1.23支持。

例子

笔记:

  • 前缀后不能有空格:owner:fehguy有效,owner: fehguy无效。
  • owner:fehguy owner:kesh92不支持具有相同前缀的多个关键字,例如。将使用最后一个。

排序

可以对搜索结果进行排序以按特定顺序显示它们。排序选项是:

  • 最佳匹配(相关性),
  • 更新日期,
  • 创立日期,
  • API或域名,
  • API 或域名 ( info.title),
  • 所有者姓名。

在 SwaggerHub SaaS 和 SwaggerHub On-Premise 1.27 中,默认排序顺序是最佳匹配,它根据搜索词在定义中出现的位置对结果进行排名。优先级如下:

  1. 该术语出现在定义名称中。
  2. 该术语出现在info.title.
  3. 该术语出现在info.description.
  4. 该术语出现在 YAML 内容的其他地方。

停用词

此信息适用于 SwaggerHub SaaS 和 SwaggerHub On-Premise 1.27。

停用词是文本中经常出现的常用词,因此会返回许多不相关的结果。例如,所有的OpenAPI定义包含infotitleversion和其他标准的关键字,所以这句话本身不是搜索有用的。搜索时,会忽略停用词以提高搜索性能。

以下 OpenAPI 关键字被视为停用词且不可搜索:

$method, $ref, $request, $response, $statusCode, $url, additionalProperties, allOf, allowEmptyValue, allowReserved, anyOf, apiKey, array, attribute, authorizationCode, authorizationUrl, basePath, basic, bearer, bearerFormat, binary, body, boolean, byte, callbacks, clientCredentials, collectionFormat, components, consumes, contact, content, contentType, cookie, csv, date, date-time, deepObject, default, definitions, delete, deprecated, description, discriminator, double, email, encoding, enum, example, examples, exclusiveMaximum, exclusiveMinimum, explode, externalDocs, externalValue, false, float, flow, flows, form, format, formData, get, head, header, headers, host, http, https, implicit, in, info, int32, int64, integer, items, label, license, links, mapping, matrix, maximum, maxItems, maxLength, maxProperties, minimum, minItems, minLength, minProperties, multi, multipleOf, name, namespace, not, null, nullable, number, oauth2, object, oneOf, openIdConnect, openIdConnectUrl, openapi, operationId, operationRef, options, parameters, password, patch, path, pathitems, paths, pattern, pipeDelimited, pipes, post, prefix, produces, properties, propertyName, put, query, readOnly, refreshUrl, requestBodies, requestBody, required, responses, schema, scheme, schemes, scopes, security, securityDefinitions, securitySchemes, server, servers, simple, spaceDelimited, ssv, string, style, summary, swagger, tags, termsOfService, title, tokenUrl, trace, true, tsv, type, uniqueItems, url, value, variables, version, wrapped, writeOnly, xml

CORS Requirements for “Try It Out”

此信息适用于 SwaggerHub SaaS 和 SwaggerHub On-Premise 1.18.7 及更高版本。

跨域资源共享 (CORS)是一种安全机制,允许来自一个域的网页访问来自另一个域的资源。

在 REST API 的上下文中,CORS 允许从远程网页上的 JavaScript 调用 API,例如从SwaggerHub 上托管的交互式文档。换句话说,您的 API 服务器必须支持 CORS 才能使“试用”请求起作用。

笔记: CORS 仅用于通过浏览器模式的路由请求。通过 SwaggerHub 代理路由请求时不使用 CORS。

启用 CORS

CORS 是服务器配置。要在您的 API 服务器上支持 CORS,您需要以下内容:

  1. API 响应必须包含 CORS 标头(见下文)。
  2. API 端点必须支持CORS 预检请求的 OPTIONS 方法。OPTIONS 必须不需要身份验证,并且应该返回带有正确 CORS 标头的 200 响应。

这些要求适用于所有 API 端点,包括 OAuth 端点。

必需的 CORS 标头

CORS 使用特殊的 HTTP 标头来允许跨域请求。“试用”功能需要 API 响应中的以下标头:

Access-Control-Allow-Origin: https://host.from.which.the.request.came
Vary: Origin
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: ResponseHeader1, ResponseHeader2, ...

访问控制允许来源

允许从指定的请求源主机访问资源。此标头的值必须设置如下:

  • 如果请求包含非空Origin标头(如从浏览器发送的请求,例如“试用”请求),则返回此来源以及Vary: Origin标头:

    Access-Control-Allow-Origin: https://host.from.which.the.request.came
    Vary: Origin
  • 如果请求没有Origin,则返回*通配符:

    访问控制允许来源:*

访问控制允许凭据:true

SwaggerHub 使用客户端凭据(浏览器 cookie、TLS 客户端证书、存储的Authorization条目)发送“试用”请求。此标头是此类请求从浏览器正常工作所必需的。

访问控制公开标题

允许浏览器访问并向用户显示的以逗号分隔的响应标头列表。例如:

Access-Control-Expose-Headers: Content-Length, ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining

如果缺少此标头,“试用”将仅显示简单的响应标头

访问控制允许标题

如果您的 API 使用 OAuth 2.0,我们建议来自 OAuth 令牌端点(由 指定tokenUrl)的 OPTIONS 响应包括Access-Control-Allow-Headers包含该X-Requested-With值的响应标头。这将防止浏览器身份验证对话框在不正确cliend_idclient_secret指定时出现。

Access-Control-Allow-Headers: X-Requested-With, <其他允许的请求头…>

Lazy Loading

此信息适用于 SwaggerHub SaaS 和 SwaggerHub On-Premise 1.20.0 及更高版本。

SwaggerHub 编辑器交互式 API 文档使用一种称为延迟加载的技术来优化外部$ref引用的加载,例如域引用。使用延迟加载,外部 $refs 仅在需要显示特定操作时才会解析和加载。

启用或禁用延迟加载(SwaggerHub On-Premise)

在 SwaggerHub On-Premise 中,默认情况下禁用延迟加载,但管理员可以根据需要启用它。

  1. 打开管理中心
  2. 选择左侧的设置
  3. 选择或取消选择启用延迟加载
  4. 单击保存更改并重新启动。等待几分钟,让系统完全重新启动。

延迟加载的工作原理

API 文档最初与折叠条目一起显示。初始渲染仅处理 API 定义,因此 API 页面加载速度快。稍后将在用户展开包含域引用的操作时加载引用的域。请注意,操作扩展将仅加载显示该特定操作所需的域。如果文档中没有展开相应的操作,则某些域可能根本无法加载。这有助于减少 API 文档加载时间并提高性能,这对于具有许多域引用的大型 API 尤其有用。

验证

延迟加载会影响编辑器中报告验证错误的方式。默认情况下,编辑器仅分析当前定义,而不分析引用的域。只有在这些域被延迟加载后,域错误才会出现在编辑器中。在验证您的 API 和域时请记住这一点。

这意味着您最初可能不会在编辑器中看到任何错误:

但是在交互式文档中展开操作时会出现错误:

一旦一个域被延迟加载,它就不会再次加载,并且在该域中发现的任何错误都将保留在 API 的错误列表中。要获取域更改,您需要在浏览器中刷新 API 页面并展开会触发该域加载的操作。

故障排除

验证整个 API

作为快速验证检查,尝试使用编辑器中的导出 > 下载 API > 解析的 YAML命令下载解析的 API 定义。如果命令成功,则表示该 API 和引用的域有效。

如果您看到如下所示的错误,则表示 API 或引用域中的某处存在语法错误。

但是,此方法只会告诉您是否有错误,而不会告诉您这些错误在哪里。要查看哪些域包含错误,请使用下面描述的方法。

查找并修复错误

要查看错误和包含这些错误的域的完整列表,请展开交互式文档中的所有内容以触发域验证。

  1. 在编辑器中打开 API。

  2. 如果 UI 面板被隐藏,请单击左侧边栏中的 查看 UI 文档以显示它。

  3. 将所有操作一一展开,在编辑器中观察验证状态。

  4. 如果操作扩展触发错误:

    • 点击 在操作信息中跳转到 YAML 代码。

    • 在操作定义中查找域引用。

      $ref: ‘https://api.swaggerhub.com/domains/...'

    • 跳转到这些域。

    • 查看域是否有语法错误并修复错误。确保保存更改。

    • 如果一个域包含对其他域的引用,也使用相同的方法(文档扩展)来验证其他域。

  5. 返回 API 并在浏览器中刷新页面。再次展开有问题的操作以获取更新的域,并确保这次没有验证错误。

  6. 继续扩展其他操作,直到您验证所有这些操作。

如果您需要语法验证方面的帮助,请询问社区、使用应用内支持聊天或打开支持票

内部 $refs 的性能提示

延迟加载仅对外部 $refs 提供性能提升,但不会影响内部 $refs ( $ref: '#/...')。如果您的 API 具有许多内部 $ref,并且加载缓慢,我们建议您将引用的定义移动到域中,并将内部 $ref 替换为域引用。延迟加载将发挥作用,以更有效地加载 API。

APIs

Creating a New API

您可以通过多种方式在 SwaggerHub 中创建 API:

您可以在您的个人帐户中或代表您创建的任何组织创建 API 。

在 SwaggerHub 中创建 API

    • OpenAPI 版本 – 选择 API 格式:OpenAPI 2.0 或 3.0。注意:OpenAPI 3.0 支持有一些限制

    • 模板 – 选择一个示例 API 开始,例如PetstoreIOT(物联网),或者选择以开始一个空白 API。

    • 名称 - API名称是其唯一的ID,是其对SwaggerHub路径的一部分,如https://app.swaggerhub.com/api/{owner}/*的PetStore** /1.0*。要求:

      • 3 到 60 个字符长
      • 允许的字符: A..Z a..z 0..9 - _ .
      • 必须以字母或数字开头和结尾

      请注意,API 名称区分大小写,因此petstorePetStore是两个不同的 API。

    • 所有者 – 选择是在您的个人帐户还是组织帐户中创建 API (如果您是 SwaggerHub 上组织的成员)。该API所有者是在SwaggerHub的API路径的一部分:https://app.swaggerhub.com/apis/*所有者*/api-name/1.0。组织拥有的 API 计入组织的限制而不是您的限制。

      笔记: 组织所有者始终可以在该组织中创建 API。如果组织配置了“组织”选项下的允许设计者创建 API ”,则具有设计者角色的成员具有“创建”权限。

    • 项目 – 如果选择一个组织作为Owner,您可以选择一个项目来添加这个 API。该列表包含您可以使用的现有项目。

      SwaggerHub 内部部署说明: 此选项是在 v. 1.23 中添加的。
    • 可见性 – 选择是将 API 设为公开还是私有。任何人都可以看到公共 API,甚至没有 SwaggerHub 帐户的人也可以看到。私有 API 只能由您和您添加为协作者的人员访问)。如果需要,您可以稍后更改 API 可见性。

    • Auto Mock API – 如果选中,SwaggerHub 将使用基本路径 https://virtserver.swaggerhub.com/{owner}/{api}/{version} 自动创建 API 模拟。这将使您在设计 API 时对其进行测试,并使开发人员无需等到 API 功能实现即可开始处理客户端应用程序。SwaggerHub 还将为您的新 API创建API Auto Mocking集成,该集成将在您每次保存 API 时自动更新模拟。有关使用模拟的更多信息,请参阅API 自动模拟

    创建空白API(无模板)时,还需要指定以下字段:

    • 版本 – API 版本。例如,1.01.0.01.0b5beta。请参阅版本格式
    • 标题 – 将显示在交互式 API 文档中的 API 标题。例如,宠物商店 API
    • 描述 – 您的 API 用途的概述。该描述将包含在 API 定义中,也会显示在 SwaggerHub 的搜索结果中。您可以稍后更改说明。
  1. 单击创建 API

创建 API 后,SwaggerHub 编辑器将打开,您可以在其中编写 API 定义。

导入 OpenAPI 定义

您可以将现有的 OpenAPI 3.0 和 OpenAPI 2.0 定义导入 SwaggerHub。JSON 和 YAML 定义都可以导入,有效的 JSON 定义会自动转换为 YAML。

对于 YAML,导入文件的大小限制为 10 MB。导入 JSON 定义时,等效 YAML 定义的最大大小为 10 MB。

导入 API

  1. 在左侧边栏中,单击 并选择导入和文档 API

  1. 将出现以下对话框:

  1. 填写字段:
  • 路径或 URL – 要导入的 API 定义的 URL 或本地路径。例如,http://petstore.swagger.io/v2/swagger.jsonC:\Work\petstore.json。要从您的计算机上传文件,请单击浏览

    笔记: 有关从 Swagger UI、GitHub 和其他网站导入定义的提示,请参阅以下示例
  • 所有者 – 选择是在您的个人帐户还是组织帐户中创建 API (如果您是 SwaggerHub 上组织的成员)。该API所有者是在SwaggerHub的API路径的一部分:https://app.swaggerhub.com/apis/*所有者*/api-name/1.0。组织拥有的 API 计入组织的限制而不是您的限制。

    笔记: 组织所有者始终可以在该组织中创建 API。如果组织配置了“组织”选项下的允许设计者创建 API ”,则具有设计者角色的成员具有“创建”权限。
  • 项目 – 如果选择一个组织作为Owner,您可以选择一个项目来添加这个 API。该列表包含您可以使用的现有项目。

    SwaggerHub 内部部署说明: 此选项是在 v. 1.23 中添加的。
  • 可见性 – 选择是将 API 设为公开还是私有。任何人都可以看到公共 API,甚至没有 SwaggerHub 帐户的人也可以看到。私有 API 只能由您和您添加为协作者的人员访问)。如果需要,您可以稍后更改 API 可见性。

  1. 单击导入

  2. 在下一页上,指定导入 API 的名称和版本:

    • 名称 - API名称是其唯一的ID,是其对SwaggerHub路径的一部分,如https://app.swaggerhub.com/api/{owner}/*的PetStore** /1.0*。要求:

      • 3 到 60 个字符长
      • 允许的字符: A..Z a..z 0..9 - _ .
      • 必须以字母或数字开头和结尾

      请注意,API 名称区分大小写,因此petstorePetStore是两个不同的 API。

      小费: 要将定义作为现有 API 的新版本导入,请输入现有 API 的名称。
    • 版本 – 导入的 API 的版本。它在定义info.version域中定义。

  3. 单击导入完成导入。

导入 API 后,SwaggerHub 编辑器将打开,您可以在其中编辑导入的 API 定义。

作为现有 API 的一个版本导入

您可以使用导入功能将 OpenAPI 定义导入为现有 API 的新版本。为此,请在导入参数中指定现有 API 的名称 (ID)。

如果 API 已经具有与info.version您正在导入的 OpenAPI 文件字段中指定的版本号相同的版本号,则该版本将被导入的定义覆盖(除非该版本已发布 - 在这种情况下,导入将被拒绝) .

Tips

从 Swagger UI 导入

在 Swagger UI 中,API 定义文件的链接通常显示在标题中和 API 标题下方。这是您需要导入到 SwaggerHub 的链接。

单击图像放大。

更多信息:如何从 Swagger UI 导出 OpenAPI JSON/YAML 文件?

从 GitHub 导入

在 GitHub 上浏览到您的 API 定义,然后单击Raw以获取指向实际文件的链接。这个链接看起来像https://raw.githubusercontent.com/...。使用此链接将您的 API 定义导入 SwaggerHub。

如果存储库是私有的,GitHub 将自动向链接添加访问令牌。

获取 GitHub 上文件的原始链接

单击图像放大。

从 Bitbucket 导入

在 Bitbucket 上浏览到您的 API 定义,然后单击省略号按钮 ( ) 并选择Open raw。使用生成的链接将您的定义导入 SwaggerHub。

笔记: 这种方法只能用于从公共存储库导入。

从 GitLab 导入

在 GitLab 上浏览到您的 API 定义,然后单击打开原始按钮以获取指向实际文件的链接。使用此链接将您的定义导入 SwaggerHub。

如果存储库是私有的,您还需要生成访问令牌并将其包含在链接中:

  1. 如果您使用 GitLab.com,请访问https://gitlab.com/profile/personal_access_tokens。如果您使用自托管 GitLab,请单击您的用户个人资料图片并选择Settings,然后选择Access Tokens

  2. 创建具有read_repositoryorapi范围的令牌。

  3. ?private_token=YOUR_TOKEN在原始链接的末尾添加:

    https://gitlab.com/MyCompany/MyProject/raw/main/openapi.yaml?private_token=YOUR_TOKEN

在 SwaggerHub 导入对话框中指定生成的链接。

Forking an API

Forking在您的帐户中创建API特定版本的副本。例如,您可以 fork 其他人的 API 作为您自己的 API 的起点。或者,您可以创建自己的 API 的分支,以在不影响原始 API 定义的情况下试验更改。

您可以分叉到您的个人帐户或您创建的任何组织

Fork 没有以任何方式链接到原始 API,因此原始 API 的更改不会影响 fork。

公共与私有 API

任何登录的 SwaggerHub 用户都可以分叉公共 API。私有 API只能由 API 所有者和该 API 的协作者进行分叉。

如何分叉 API

  1. 在 SwaggerHub 中打开 API 页面。

  2. 如果 API 有多个版本,请选择要分叉的版本。

  3. 单击 API 名称。这将打开 API 信息面板。

  4. 叉 在 API 信息面板中单击。

  5. 输入叉的名称并指定其他详细信息。

    • API名称 -您的API的ID,这将是SwaggerHub的API URL的一部分,如https://app.swaggerhub.com/api/{owner}/*的PetStore** /1.0*。

      ID 的长度必须至少为 3 个字符,并且必须以字母或数字开头和结尾。您可以使用英文字母 (A..Z, a..z)、数字 (0..9)、点 (.)、连字符 (-) 和下划线 (_)。ID 区分大小写,因此petstorePetStore是两个不同的 API。

    • API 版本 – API 版本。例如,1.01.0.01.0b5beta(请参阅版本格式)。它不一定需要匹配您正在分叉的 API 版本,因为分叉将是一个完全不同的 API。

    • 所有者 – 选择是在您的个人帐户还是组织帐户中创建 API (如果您是 SwaggerHub 上组织的成员)。该API所有者是在SwaggerHub的API路径的一部分:https://app.swaggerhub.com/apis/*所有者*/api-name/1.0。组织拥有的 API 计入组织的限制而不是您的限制。

      笔记: 组织所有者始终可以在该组织中创建 API。如果组织配置了“组织”选项下的允许设计者创建 API ”,则具有设计者角色的成员具有“创建”权限。
    • 项目 – 如果选择一个组织作为Owner,您可以选择一个项目来添加这个 API。该列表包含您可以使用的现有项目。

      SwaggerHub 内部部署说明: 此选项是在 v. 1.23 中添加的。
    • 可见性 – 选择是将 API 设为公开还是私有。任何人都可以看到公共 API,甚至没有 SwaggerHub 帐户的人也可以看到。私有 API 只能由您和您添加为协作者的人员访问)。如果需要,您可以稍后更改 API 可见性。

  6. 单击Fork API

SwaggerHub 会将 API 复制到指定的所有者帐户,并将在SwaggerHub 编辑器中打开 API 定义,您可以在其中进行编辑。

笔记

  • Forking 不会复制原始 API 中存在的集成注释。这是为了保护原始 API 的完整性而设计的。
  • “另存为新的”命令是另一种方式,以现有的规范复制到一个新的API规范。此命令仅适用于您可以在 SwaggerHub 中编辑的 API。Forking 可用于任何可访问的 API 规范。

Saving an API as a New API

您可以通过从 SwaggerHub 中存在的另一个 API 复制它来创建 API。您可以使用此功能将某些现有规范用作 API 规范的起点,或者您可以创建副本以试验更改而不影响原始规范。

要使用此功能,您必须是原始 API的所有者,或者您必须拥有它的编辑权限

新 API 可以属于您的个人帐户或您创建的任何组织

怎么运行的

  1. 打开您的 API 规范之一进行编辑。

    选择需要的版本:

    如果需要,对规范进行更改。

  2. 选择另存为新命令:

    这将打开以下对话框:

  3. 在对话框中,输入以下数据:

    • API名称 - API名称是其唯一的ID,是其对SwaggerHub路径的一部分,如https://app.swaggerhub.com/api/{owner}/*的PetStore** /1.0*。要求:

      • 3 到 60 个字符长
      • 允许的字符: A..Z a..z 0..9 - _ .
      • 必须以字母或数字开头和结尾

      请注意,API 名称区分大小写,因此petstorePetStore是两个不同的 API。

    • API 版本 – 新 API 的初始版本。例如,1.01.0.01.0b等。请参阅版本格式

    • 所有者 – 选择是在您的个人帐户还是组织帐户中创建 API (如果您是 SwaggerHub 上组织的成员)。该API所有者是在SwaggerHub的API路径的一部分:https://app.swaggerhub.com/apis/*所有者*/api-name/1.0。组织拥有的 API 计入组织的限制而不是您的限制。

      笔记: 组织所有者始终可以在该组织中创建 API。如果组织配置了“组织”选项下的允许设计者创建 API ”,则具有设计者角色的成员具有“创建”权限。
    • 项目 – 如果选择一个组织作为Owner,您可以选择一个项目来添加这个 API。该列表包含您可以使用的现有项目。

      SwaggerHub 内部部署说明: 此选项是在 v. 1.23 中添加的。
    • 可见性 – 选择是将 API 设为公开还是私有。任何人都可以看到公共 API,甚至没有 SwaggerHub 帐户的人也可以看到。私有 API 只能由您和您添加为协作者的人员访问)。如果需要,您可以稍后更改 API 可见性。

  4. 点击保存

Publishing an API

当您觉得您的 API 定义已准备好用于生产时,您可以发布它。发布是一种表明 API 处于稳定状态并且可以从其他应用程序可靠地调用其端点的方式。

发布使 API 定义为只读,因此您在此之后所做的任何更改都应保存为API的新版本协作者也无法编辑已发布的版本。

已发布和未发布的 API 之间的区别

区别主要在于语义:

  • 一个未公开的API定义是一个草案,在正在进行的工作。SwaggerHub 中的每个 API 一开始都未发布。尽管未发布的 API 列在 SwaggerHub 注册表中,但它们尚未准备好供 API 使用者使用。
  • 公布的API定义是一个稳定版本准备好从客户端应用程序消耗。它不应被更改,任何更改都将作为 API 的新版本引入。

从技术上讲,区别在于发布的 API 版本无法编辑(除非您取消发布它们)。如果您想更改某些内容,您应该创建一个新版本的 API 并在其中进行更改。

SwaggerHub 在已发布的API 和域旁边显示已发布标签。搜索 SwaggerHub 的人还可以过滤列表以仅显示已发布的 API。

已发布/未发布与公共/私人

已发布和未发布与public 和 private 不同。公共和私有表示谁可以在 SwaggerHub 中看到 API——每个人或只是选定的合作者。已发布和未发布表示生产准备就绪——API 是否已准备好供使用。

发布 API 版本

API 所有者和具有编辑器角色的协作者可以发布 API 版本。

  1. 转到 SwaggerHub 中的 API 页面。

  2. 如果 API 有多个版本,请选择您要发布的版本。

  3. 打开版本列表并单击 发布版本

  4. (可选。)选择设置为默认版本以使该版本成为您的 API的默认版本

  5. 单击发布版本

发布后,API 版本将变为只读且无法编辑。如果您需要添加新端点、更改参数等,您应该创建 API 的新版本并在那里进行更改。但是,如果您需要对已发布的 API 进行一些重要更改,您可以暂时取消发布它

笔记: 当 API 发布或取消发布时,所有协作者都会收到电子邮件通知。

取消发布 API 版本

如果您改变主意并希望拉回 API 定义以进行一些更改,您可以取消发布 API。为此,您必须是 API 所有者或具有编辑者角色的协作者。

  1. 在 SwaggerHub 编辑器中打开 API。

  2. 如果 API 有多个版本,请切换到您要取消发布的版本。

  3. 打开版本列表,然后单击 取消发布版本

  4. 在对话框中,单击取消发布版本

现在可以再次编辑此 API 版本。

通过 CLI 发布和取消发布

使用SwaggerHub CLI 从命令行发布和取消发布您的 API。

发布:

swaggerhub api:发布所有者/API_NAME/VERSION

取消发布:

swaggerhub api:取消发布所有者/API_NAME/VERSION

api:create并且api:update还可以--published=publish|unpublish选择:

swaggerhub api:更新所有者/API_NAME/VERSION –file myapi.yaml –published=publish

版本控制

SwaggerHub 允许您管理 API 或定义的多个版本。当您需要添加新的 API 操作或参数、添加数据模型等时,您通常会启动一个新版本。一旦新版本准备好供客户端应用程序使用,您就可以发布它。通过这种方式,您可以不断增强 API,同时为 API 使用者提供干净的发布版本。

版本列表

所有版本都列在 API(域)名称旁边的下拉列表中,因此您只需单击几下即可在版本之间切换。

API 版本也存储在info.versionOpenAPI (Swagger) 定义中的密钥中:

info:
  title: Petstore
  version: 1.0.0

API 版本不相互依赖。它们可以有不同的 API 操作、参数、描述等。以下内容是特定于版本的,不会在版本之间共享:

版本格式

通常,版本号看起来像 1.0.0,但它们实际上可以包含以下任何字符:

0-9 A-Z a-z . _ -

注意:版本号必须以数字或字母开头和结尾。

以下是有效版本号的示例:

1
1.0
0.0.1
1.2.3.4
2.4_15
1.0b5
1.2.0-rc3
v1
beta
2016-04-15

您可以选择任何版本控制方案,但我们建议使用语义版本控制,它使用格式为major.minor.patch.

添加新版本

任何对 API 具有编辑权限的人都可以创建和删除版本。这包括 API 所有者和具有编辑器角色的协作者

有多种方法可以将新版本添加到 API 或域。

笔记: 当您创建新的 API 版本时,您还可以将一些现有的集成转移到新版本中。

选项1

打开版本号旁边的下拉菜单,选择Create New Version,然后输入新版本号。新版本将包含与当前版本相同的内容。

选项 2

您可以versioninfoAPI 或域的部分中更改。如果执行此操作,“保存”按钮将更改为“创建新版本”。单击它可将内容另存为新版本。

注意:这仅适用于未发布的 API 和域,因为已发布的 API 是只读的且无法编辑。

版本排序

如果 API 或域使用语义版本控制 ( major.minor.patch),则 SwaggerHub 编辑器按降序显示版本,最新版本在顶部。其他格式的版本号按创建顺序显示。

设置默认版本

默认版本是在 SwaggerHub 的搜索结果中显示的版本,或者当有人在没有特定版本号的情况下直接导航到您的 API 或域定义时显示的版本,例如https://app.swaggerhub.com/api/swagger-hub/registry- api/ . 在编辑器中,默认版本标有 图标。

要更改默认版本,请单击该版本旁边的img 设置为默认值

此外,当您创建新版本或发布版本时,您可以将此版本设置为默认版本:

查看谁创建了版本

您可以在“信息”面板底部看到谁创建了 API 或域版本:

注:创建信息仅适用于人的API和域的版本:

  • 2019 年 11 月 26 日之后在 SwaggerHub SaaS 中创建,
  • 在 SwaggerHub On-Premise 1.23 及更高版本中创建。

可以在历史审计日志中找到有关早期版本的信息。

重命名版本

没有直接的方法来重命名版本,但您可以使用以下解决方法:

  1. 切换到要重命名的版本。
  2. 创建具有所需版本号的新版本
  3. 删除旧版本。

比较版本

您可以比较两个 API 版本以了解它们的不同之处。要做到这一点:

  1. 打开您的 API 并选择您要比较的版本之一。

  2. 在版本列表中,单击 在要比较的版本旁边。

这将打开差异视图,您可以在其中查看版本之间的差异。

您还可以比较不同 API 的版本,如比较和合并 API 版本中所述

删除版本

如果您的 API 有两个或更多版本,您可以删除不再需要的旧版本。此操作无法撤消。请注意,如果 API 只有一个版本,您可以删除该 API

笔记: 您只能删除未发布的版本。如果发布了版本,需要先取消发布:选择该版本,点击img

要删除版本,请单击 在版本列表中该版本旁边:

API 文档的自定义品牌

*注意:在 SwaggerHub SaaS、SwaggerHub On-Premise 1.20.0 及更高版本中可用。*

组织可以将自定义品牌添加到 SwaggerHub 上的 API 文档中。品牌选项包括自定义徽标和标题颜色,它们将显示在API 和域的面向消费者的文档中。

SwaggerHub 上的自定义文档品牌

计划

Docs Branding 适用于使用 Team 和 Enterprise 计划的组织。团队计划将在自定义徽标下显示额外的“由 SwaggerHub 提供支持”徽章。

标志要求

  • PNG 或 JPG
  • 小于 2 MB

为获得最佳效果,请使用:

  • 具有透明背景的 PNG 图像
  • 尺寸最大为 230×55 像素的图像(较大的图像将按比例缩小以适应此尺寸)

应用品牌

组织所有者可以在组织设置的Docs Branding页面上配置品牌选项:

  1. 单击您的用户名并选择Settings

  2. 切换到我的组织选项卡。

  3. 单击 组织名称旁边的。

  4. 在左侧边栏中选择Docs Branding

  5. 指定品牌选项:

    • 上传标志 – 将您的图像拖放到上传区域,或单击上传区域手动选择图像。确保徽标图像符合要求

      小费: 要裁剪或调整徽标大小,请单击 编辑和使用图像编辑器(见下文)。
    • 替代文本 – HTML 代码中alt徽标<img>标签属性的文本。例如,YourCompanyName

    • 标题样式 – 文档标题颜色为十六进制 HTML 颜色代码,#xxxxxx. 您可以使用[Google 颜色选择器](https://www.google.com/search?q=color picker)来查找十六进制颜色值。

  6. 单击保存草稿。此时,品牌设置已保存,但尚未应用。

  7. 单击预览以查看您的品牌在示例 API 中的外观。

  8. 最后,点击去住以应用自定义品牌。

您组织的 API 和域的文档页面现在将显示您的自定义徽标。

裁剪或调整徽标大小

您可以根据需要裁剪上传的徽标并调整其大小。为此,请单击 在徽标下编辑并使用徽标编辑器工具。

要裁剪徽标,请单击 裁剪,然后绘制裁剪区域的边缘,或手动输入新尺寸。您还可以单击裁剪区域并将其拖动到其他位置。准备好后,单击应用

要调整徽标大小,请单击 缩放,然后拖动角以调整徽标大小,或手动输入新尺寸。准备好后,单击应用注意:徽标的最大尺寸为 230×50 像素。

撤消按钮可让您撤消上一个操作。

对新徽标大小感到满意后,请关闭徽标编辑器,然后单击“保存草稿并上线

更换标志

  1. 打开组织设置的Docs Branding页面。
  2. 将新徽标拖放到徽标区域,或单击徽标手动选择新文件。
  3. 单击“保存草稿”,然后单击“上线”

恢复默认样式

要恢复 API 文档中的默认 SwaggerHub 徽标和标题颜色:

  1. 打开组织设置的Docs Branding页面。
  2. 通过单击删除徽标 删除
  3. 删除替代文本标题样式值。
  4. 单击“保存草稿”,然后单击“上线”

比较和合并 API 版本

SwaggerHub 有一个内置的差异工具,可让您比较和合并 API 定义。你可以:

  • 比较相同 API 的版本
  • 将 API 定义与 SwaggerHub 上的另一个 API 或外部 API 定义进行比较。

要求

  • 被比较的 API 定义必须是有效的 YAML。
  • 要使用“比较和合并”工具,您必须在当前 API 中具有编辑权限。

比较相同 API 的版本

  1. 在 SwaggerHub 编辑器中打开 API。

  2. 切换到要比较的版本之一。

  3. 点击 在要比较的版本旁边。

与 SwaggerHub 上的另一个 API 进行比较

  1. 在 SwaggerHub 编辑器中打开您的 API。

  2. 如果您的 API 有多个版本,请切换到您要比较的版本。

  3. 单击 API 名称。这将打开 API 信息面板。

  4. 在 API 信息面板中单击。

  5. 在 SwaggerHub 上选择与 API 比较

  6. 指定要与之进行比较的 API 的所有者、名称和版本。

  7. 单击下一步继续差异视图

与外部 API 定义进行比较

  1. 在 SwaggerHub 编辑器中打开您的 API。

  2. 如果您的 API 有多个版本,请切换到您要比较的版本。

  3. 单击 API 名称。这将打开 API 信息面板。

  4. 在 API 信息面板中单击。

  5. 选择与外部 API 比较

  6. 指定要与之进行比较的 YAML 或 JSON 定义的 URL。要从您的计算机上传文件,请单击浏览

  7. 单击“获取”以继续。

差异视图

diff 视图如下所示,右侧是当前 API 版本,左侧是其他版本。添加的行以绿色突出显示,修改的行 - 蓝色,删除的行 - 红色。

底部的比较类型选项控制要比较的内容:

比较类型 描述
设计 + 元数据 比较 OpenAPI 密钥和密钥值。
仅设计 仅检查结构,例如新的或删除的 OpenAPI 密钥。键值的差异被忽略。

定义中的键顺序不被视为差异,除非您更改了键值或添加或删除了某些键。

(可选)合并差异

  1. 单击窗口右侧或左侧部分突出显示的差异线(或块)。SwaggerHub 会将块从窗口左侧复制到右侧(即,复制到您的 API)并将删除突出显示。它还将增加撤消按钮中的计数器。
  2. 如果需要,单击撤消以恢复最近的批准。要恢复多次批准,请多次单击“撤消”
  3. 合并所有需要的差异后,单击保存更改以保存更改。这将使用选定的更改更新当前版本

从 SwaggerHub 下载 OpenAPI 定义

SwaggerHub 允许您以 YAML 或 JSON 格式下载任何 API 或的 OpenAPI (Swagger) 定义。

从 SwaggerHub 编辑器下载

  1. 在 SwaggerHub 编辑器中打开 API。

  2. 如果 API 有多个版本,请选择您要下载的版本。

  3. 从“导出”菜单中,选择“下载 API”,然后选择所需的格式 - YAML 或 JSON。

可以选择下载已解析或未解析的定义。如果您的定义包含外部$ref 链接,例如到域的链接,这会有所不同。

  • 未解析意味着不会解析外部链接,生成的文件将包含$ref在编辑器中出现的链接。
  • Resolved意味着外部链接将被解析,即外部文件的内容将包含在结果定义中。

通过 URL 下载

公共 API

一个快速的方法来下载OpenAPI的定义从SwaggerHub是取代appapi在地址栏,如下图所示。如果 URL 以指向标记或操作的永久链接结尾,例如#/pets,请删除该部分。

在 SwaggerHub On-Premise 中,/v1改为在主机名后添加:

下载 URL 格式如下:

https://api.swaggerhub.com/apis/{owner}/{api}/{version}         # SwaggerHub SaaS
http(s)://{swaggerhub-host}/v1/apis/{owner}/{api}/{version}     # SwaggerHub On-Premise

您还可以使用 cURL 等工具从 SwaggerHub 下载定义:

curl https://api.swaggerhub.com/apis/swagger-tutorials/petstore/1.0.0

这会将 API 定义下载为 JSON。如果您需要 YAML,请在末尾附加/swagger.yaml,或使用Accept: application/yaml标头:

curl https://api.swaggerhub.com/apis/swagger-tutorials/petstore/1.0.0/swagger.yaml
curl -H "Accept: application/yaml" https://api.swaggerhub.com/apis/swagger-tutorials/petstore/1.0.0

已解析的 YAML/JSON

此信息适用于 SwaggerHub SaaS、SwaggerHub On-Premise 1.25.0 及更高版本。

要获取解析的API 定义,请附加?resolved=true到下载 URL。

已解决的 YAML:

https://api.swaggerhub.com/apis/{owner}/{api}/{version}/swagger.yaml?resolved=true

解析的 JSON:

https://api.swaggerhub.com/apis/{owner}/{api}/{version}?resolved=true

在内部部署的 SwaggerHub 中:

http(s)://{swaggerhub-host}/v1/apis/{owner}/{api}/{version}/swagger.yaml?resolved=true
http(s)://{swaggerhub-host}/v1/apis/{owner}/{api}/{version}?resolved=true

私有 API

如果 API 定义是私有的,请添加Authorization: API_KEY包含您的 SwaggerHub API 密钥的标头 :

curl -H "Authorization: API_KEY" https://api.swaggerhub.com/apis/{owner}/{api}/{version}

Maven 和 Gradle 插件

SwaggerHub 具有MavenGradle插件,允许您下载 API 定义作为 CI/CD 管道的一部分。

转让 API 所有权

您可以在 SwaggerHub 中将 API 传输给其他用户或组织。除非新所有者具有将所有权归还给前所有者的良好意愿,否则此操作无法撤消

当个人 API 转移给新的所有者时,之前的所有者将被添加为具有编辑权限的协作者

转让所有权所需的权限

在 SwaggerHub SaaS 和 SwaggerHub On-Premise v. 1.23 及更高版本中,具有以下权限的用户可以传输 API:

转移方向 需要权限
从个人账户 所有者
从一个组织 对该 API 具有编辑权限的组织所有者或设计者
给一个组织 具有创建权限的组织所有者或设计者

在早期的 SwaggerHub 内部部署版本中,只有所有者可以转让所有权。

所有权转让

SwaggerHub SaaS、SwaggerHub On-Premise v. 1.23 及更高版本

  1. SwaggerHub 编辑器中打开 API 。

  2. 单击 API 名称。这将打开 API 信息面板。

  3. 单击 管理所有者和项目

  4. 选择要将 API 传输到的组织。

  5. 如果 API 已配置集成,您可以选中传输集成复选框以随集成传输 API。注意:这将使新所有者可以访问集成设置,包括访问令牌。

  6. (可选。)选择要添加此 API的项目。该列表包含您所属的现有项目。

  7. 选择是,我要继续复选框。

  8. 点击保存

SwaggerHub On-Premise v. 1.22 及更早版本

  1. 在 SwaggerHub 编辑器中打开 API。

  2. 单击 API 名称。这将打开 API 信息面板。

  3. 在 API 信息面板中单击。

  4. 输入要将 API 传输到的组织或用户的名称:

  5. 输入 API 名称以确认传输:

  6. (可选。)选中Transfer Integrations复选框以授予新所有者访问集成设置和令牌的权限。

  7. 单击传输 API

生成代码

SwaggerHub 允许您根据 API 定义生成服务器和客户端代码,以帮助您快速启动并运行 API 服务器和客户端。您还可以配置集成 以自动将生成的代码推送到 GitHub、GitLab、Bitbucket 或 Azure DevOps 上的存储库。

OpenAPI 2.0 和 3.0 都支持代码生成。

生成服务器存根

使用 SwaggerHub,您可以轻松地为 Node.js、ASP.NET、JAX-RS 和其他服务器和框架生成服务器存根(API 实现存根)。服务器存根是实现 API 的良好起点——您可以在本地运行和测试它,实现 API 的业务逻辑,然后将其部署到您的服务器。

任何人都可以为 SwaggerHub 中的任何 API 生成服务器存根,除非 API 所有者在代码生成选项中禁用了服务器生成。

下载服务器存根

  1. 在 SwaggerHub 中打开 API 页面。

  2. 如果 API 有多个版本,请选择要为其生成代码的版本。

  3. 从“导出”菜单中,选择“服务器存根”,然后选择所需的语言或框架。

    笔记: 标有星号 * 的语言使用 API 编辑器配置的自定义代码生成选项。

  4. 下载并解压服务器代码。

代码生成选项

API 所有者可以为其 API自定义代码生成选项

自定义服务器生成器

SwaggerHub On-Premise 允许公司创建和使用自定义代码生成器。要了解更多信息,请参阅使用自定义 Codegen 模板

我已经下载了服务器存根。怎么办?

您可以在本地运行和测试生成的服务器。请注意,生成的 API 代码仅包含不包含任何实际编程逻辑的存根方法。您需要自己实现逻辑来处理 API 需要做的任何工作。实现准备就绪后,您可以在本地或服务器上部署 API。请参阅下载的存档中的 README.md 文件以开始使用。

生成客户端 SDK

SwaggerHub 允许您为 JavaScript、Java、C#、Objective C、Swift、Android 和许多其他语言的 API 生成客户端 SDK(列表不断扩展)。客户端 SDK 包含包装类,您可以使用这些包装类从您的应用程序调用 API,而无需处理 HTTP 请求和响应。

任何人都可以为任何 API 生成 SDK - 您不需要 SwaggerHub 帐户或成为 API 所有者。

下载客户端 SDK

  1. 在 SwaggerHub 中打开 API 页面。

  2. 如果 API 有多个版本,请选择要为其生成代码的版本。

  3. 导出菜单中,选择Client SDK,然后选择所需的语言或框架。

    笔记: 标有星号 * 的语言使用 API 编辑器配置的自定义代码生成选项。

  4. 下载并解压 SDK。

代码生成选项

API 所有者可以为其 API自定义代码生成选项

自定义客户端生成器

SwaggerHub On-Premise 允许公司创建和使用自定义代码生成器。要了解更多信息,请参阅使用自定义 Codegen 模板

我已经下载了客户端 SDK。怎么办?

这取决于您使用的语言。通常,SDK 并非设计为独立工作——您需要创建一个应用程序,该应用程序将使用此 SDK 进行 API 调用。请参阅下载的存档中的 README.md 文件以开始使用。

代码生成选项

SwaggerHub 允许您为各个 API 的服务器存根客户端 SDK自定义代码生成选项。每种语言或框架都有其特定的选项,例如包名称、导入映射等。

您还可以从API 页面的导出菜单中隐藏特定语言,例如,如果您不希望 API 平台支持某些语言。

注意事项

  • 代码生成选项适用于通过导出菜单下载的代码,以及源代码控制集成(GitHub、Bitbucket 等)生成的代码。
  • 代码生成选项适用于特定的 API版本。它们不会在版本之间共享,也不会在您创建新版本或分叉 API 时复制。

更改代码生成选项

要更改代码生成选项,您必须是 API 所有者或具有编辑器角色的协作者

  1. 在 SwaggerHub 编辑器中打开您的 API。

  2. 如果 API 有多个版本,请选择要更改代码生成选项的版本。

  3. 从“导出”菜单中,选择“代码生成选项”

编辑代码生成选项对话框中列出了所有可用的语言和代码生成框架。选择一种语言以查看其选项。

按钮的工作方式如下:

  • 隐藏选项 - 从API 页面的下载菜单中隐藏所选语言。要再次添加语言,请单击显示选项
  • 删除 - 恢复所选语言的原始选项。如果语言被隐藏,它将再次显示。
  • 还原 - 取消您在当前编辑会话期间所做的任何未保存的更改。这与Delete不同,后者会恢复所做的所有更改。

Domains

是常见组件库-如参数,响应和数据模型-跨多个API定义使用。可以使用 OpenAPI 2.0 或 OpenAPI 3.0 语法编写域。API 定义可以使用具有匹配 OpenAPI 版本的域。

创建域

您可以从头开始创建一个新域,然后向其中添加内容,也可以像分叉 API 一样分叉现有域

要创建新域:

  1. 在任何页面的左上角,单击 并选择创建新域

  2. 输入域信息:

    • OpenAPI 版本 – 选择域格式:OpenAPI 2.0 或 3.0。注意:OpenAPI 3.0 支持有一些限制

    • 名称 -域名是其唯一的ID,是其对SwaggerHub URL的一部分,如https://app.swaggerhub.com/domains/{owner}/*公共*/1.0

      要求:

      • 3 到 60 个字符长
      • 允许的字符: A..Z a..z 0..9 - _ .
      • 必须以字母或数字开头和结尾
      笔记: 域名区分大小写,因此commonsCommons是两个不同的域。
    • 版本 – 域的版本号。例如 1.0、1.0.0、1.0rc5、beta、2016-04-15 等。请参阅版本格式

    • 所有者 – 选择是在您的个人帐户还是组织帐户中创建域(如果您是 SwaggerHub 上组织的成员)。域所有者是 SwaggerHub 中域路径的一部分:https://app.swaggerhub.com/domains/ *companyname** /{domain-name}/1.0*。组织拥有的域计入组织的限制而不是您的限制。

      笔记: 组织所有者始终可以在该组织中创建域。如果组织配置了“组织”选项下的允许设计者创建 API ”,则具有设计者角色的成员具有“创建”权限。
    • 项目 – 如果选择一个组织作为所有者,您可以选择性地选择一个项目以将此域添加到。该列表包含您可以使用的现有项目。

      SwaggerHub 内部部署说明: 此选项是在 v. 1.23 中添加的。
    • 可见性 – 选择域是公开的(您公司中的任何人都可以看到)还是私有的(只能由您和与您共享域的合作者访问)。有关详细信息,请参阅公共和私有 API

  3. 单击创建域

引用域

API 可以使用关键字从域中引用共享组件$ref。域引用具有以下格式:

# OpenAPI 2.0
$ref: https://api.swaggerhub.com/domains/OWNER/DOMAIN/VERSION#/TYPE/COMPONENT_NAME

# OpenAPI 3.0
$ref: https://api.swaggerhub.com/domains/OWNER/DOMAIN/VERSION#/components/TYPE/COMPONENT_NAME
笔记: 域引用中的 SwaggerHub 主机名以 开头api,而不是以app.

在 SwaggerHub On-Premise 中,域引用需要/v1在主机名之后:

# OpenAPI 2.0
$ref: http(s)://SWAGGERHUB/v1/domains/OWNER/DOMAIN/VERSION#/TYPE/COMPONENT_NAME

# OpenAPI 3.0
$ref: http(s)://SWAGGERHUB/v1/domains/OWNER/DOMAIN/VERSION#/components/TYPE/COMPONENT_NAME

例如,您将从域中引用Order架构common-models,如下所示:

openapi: 3.0.0

paths:
  /orders:
    post:
      summary: Add a new order
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: 'https://api.swaggerhub.com/domains/acme/common-models/1.0#/components/schemas/Order'

自动完成

插入域引用的最简单方法是使用自动完成:键入$ref:后跟一个空格,然后按CTRL+SPACE(在 Windows 上)或OPTION+SPACE(在 Mac 上)。SwaggerHub 编辑器将显示建议列表。从列表中选择一个项目,SwaggerHub 将插入一个完全限定的$ref.

单击图像放大。

在 SwaggerHub SaaS 中,自动完成仅显示本地定义以及与 API 所有者相同所有者的域。但是,您也可以通过手动指定相应的值来引用任何其他公共或共享的私有$ref

在 SwaggerHub On-Premise 1.21.0 及更高版本中,自动完成还会显示当前用户有权访问的任何域,包括所有公共域、用户所属的所有组织的域以及用户是协作者的所有域.

引用规则

  • API 只能引用具有相同 OpenAPI 版本的域:
    • OpenAPI 2.0 API 可以引用 OpenAPI 2.0 域。
    • OpenAPI 3.0 API 可以引用 OpenAPI 3.0 域(跨任何openapi: 3.0.x版本)
  • 域可以使用相同的规则引用其他域。
  • 域引用根据当前用户的访问权限进行解析。用户至少需要对引用域的读取访问权限才能解析引用。

跳转到引用的域

将鼠标悬停在编辑器中的域链接上,然后单击Jump To。SwaggerHub 将在新的浏览器选项卡中打开此域。

管理域

您可以像管理 API 定义一样管理。例如,您可以:

OpenAPI 3.0 Domain Example

下面是一个 OpenAPI 3.0定义示例,演示了各种类型的域组件。

另请参阅:OpenAPI 2.0 域示例

# OpenAPI version identifier - required for OpenAPI 3.0 domains
openapi: 3.0.0

#######################
# Optional info section
#######################
info:
  title: Acme Components
  description: Common components for Acme REST APIs
  version: 1.0.0

components:

  ####################
  # Common data models
  ####################
  schemas:
    ErrorModel:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: integer
          format: int32
        message:
          type: string

  ####################
  # Common parameters
  ####################
  parameters:
    offsetParam:
      name: offset
      in: query
      schema:
        type: integer
        minimum: 0
      description: The number of items to skip before returning the results
    limitParam:
      in: query
      name: limit
      schema:
        type: integer
        format: int32
        minimum: 1
        maximum: 100
        default: 20
      description: The number of items to return

  #######################
  # Common request bodies
  #######################
  requestBodies:
    NewItem:
      description: A JSON object containing item data
      required: true
      content:
        application/json:
          schema:
            type: object
          examples:
            tshirt:
              $ref: '#/components/examples/tshirt'

  ####################
  # Common responses
  ####################
  responses:
    GeneralError:
      description: An error occurred
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorModel'
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'

  #########################
  # Common headers
  # (except request headers - they are defined as parameters)
  #########################
  headers:
    X-RateLimit-Limit:
      description: Request limit per hour
      schema:
        type: integer
      example: 100
    X-RateLimit-Remaining:
      description: Remaining requests for the hour
      schema:
        type: integer
      example: 94

  #######################
  # Common path items
  #######################
  pathitems:
    EntityOperations:
      get:
        summary: Get all items
        description: This operation supports pagination
        parameters:
          - $ref: '#/components/parameters/offsetParam'
          - $ref: '#/components/parameters/limitParam'
        responses:
          '200':
            description: A list of items
            headers:
              X-RateLimit-Limit:
                $ref: '#/components/headers/X-RateLimit-Limit'
              X-RateLimit-Remaining:
                $ref: '#/components/headers/X-RateLimit-Remaining'
          default:
            $ref: '#/components/responses/GeneralError'
      post:
        summary: Add a new item
        requestBody:
          $ref: '#/components/requestBodies/NewItem'
        responses:
          '201':
            description: Created
            headers:
              X-RateLimit-Limit:
                $ref: '#/components/headers/X-RateLimit-Limit'
              X-RateLimit-Remaining:
                $ref: '#/components/headers/X-RateLimit-Remaining'

  ######################################
  # Common examples of input/output data
  ######################################
  examples:
    tshirt:
      summary: Sample T-shirt data
      value:
        # Example value starts here
        id: 17
        name: T-shirt
        description: 100% cotton shirt
        categories: [clothes]

  #########################
  # Common link definitions
  # See: https://swagger.io/docs/specification/links/
  #########################
  links: {}

  #########################
  # Common callback definitions
  # See: https://swagger.io/docs/specification/callbacks/
  #########################
  callbacks: {}

OpenAPI 2.0 Domain Example

下面是一个示例 OpenAPI 2.0定义,演示了各种类型的域组件。

另请参阅:OpenAPI 3.0 域示例

# OpenAPI version identifier - optional for OpenAPI 2.0 domains
swagger: '2.0'

######################
# Optional info section
######################
info:
  title: Components
  description: Common components for Acme REST APIs
  version: 1.0.0

####################
# Common data models
####################
definitions:
  ErrorModel:
    type: object
    required:
      - code
      - message
    properties:
      code:
        type: integer
        format: int32
      message:
        type: string

####################
# Common parameters
####################
parameters:
  offsetParam:
    name: offset
    in: query
    type: integer
    minimum: 0
    description: The number of items to skip before returning the results
  limitParam:
    in: query
    name: limit
    type: integer
    format: int32
    minimum: 1
    maximum: 100
    default: 20
    description: The number of items to return

####################
# Common responses
####################
responses:
  GeneralError:
    description: An error occurred
    schema:
      $ref: '#/definitions/ErrorModel'

####################
# Common path items
####################
pathitems:
  EntityOperations:    # In domains, path item names do not have to be actual paths
    get:
      summary: Get all items
      description: This operation supports pagination
      parameters:
        - $ref: '#/parameters/offsetParam'
        - $ref: '#/parameters/limitParam'
      responses:
        200:
          description: A list of items
        default:
          $ref: '#/responses/GeneralError'
    post:
      summary: Add a new item
      parameters:
        - in: body
          name: item
          schema:
            type: object
      responses:
        201:
          description: Created

Open Source Tools

Swagger Editor

Swagger Editor 是一个开源编辑器,用于在 Swagger 规范中设计、定义和记录 RESTful API。Swagger 编辑器的源代码可以在 GitHub 中找到。

GitHub: https://github.com/swagger-api/swagger-editor

下载

在 Web 上使用编辑器

编辑器可在任何 Web 浏览器中运行,并且可以在本地托管或从 Web 访问。

带我去网页版

在本地机器上使用编辑器

您也可以在您的机器上运行和使用 Swagger 编辑器。

先决条件

在下载和运行 Swagger 编辑器之前,需要在您的计算机上安装以下依赖项。

成功安装 NodeJS 后,请使用以下命令安装所有 npm 依赖项

npm install;
使用 GitHub 中的 http-server 模块进行设置

Swagger 编辑器可以在 GitHub 上的这个 公共存储库中找到

请运行以下命令以使用来自 GitHub 的 http-server 模块运行编辑器。从 Github 下载最新版本后,您需要在终端上运行这些脚本。

npm install -g http-server
wget https://github.com/swagger-api/swagger-editor/releases/download/v2.10.4/swagger-editor.zip
unzip swagger-editor.zip
http-server swagger-editor
从 Docker 设置

Swagger 编辑器可以在 Docker 上的这个公共存储库中找到 。

请运行以下命令以从 Docker 在本地机器上运行编辑器。

docker pull swaggerapi/swagger-editor
docker run -p 80:8080 swaggerapi/swagger-editor

贡献

Swagger Editor 是 Apache 许可下的一个开源项目。您可以通过Swagger Editor GitHub 存储库中的建议、想法、错误报告和拉取请求为项目做出贡献 。

请运行以下命令以查看编辑器的源代码并在您的本地机器上处理该项目。

git clone https://github.com/swagger-api/swagger-editor.git
cd swagger-editor
npm install
npm run build
npm start

常见问题:

  • 如果 npm start 不起作用,请删除 node_modules 文件夹,然后运行 npm installnpm start
  • 如果 克隆后dist文件夹有问题 ,到root运行 npm run build

Swagger UI

Installation

发布渠道

NPM 注册表

我们向 npm 发布了两个模块:swagger-uiswagger-ui-dist.

swagger-ui供包含模块打包器的 JavaScript Web 项目使用,例如 Webpack、Browserify 和 Rollup。它的主文件导出 Swagger UI 的主要功能,该模块还包括一个命名空间样式表,位于swagger-ui/dist/swagger-ui.css. 下面是一个例子:

import SwaggerUI from 'swagger-ui'
// or use require if you prefer
const SwaggerUI = require('swagger-ui')
SwaggerUI({
  dom_id: '#myDomId'
})

有关详细信息,请参阅Webpack 入门示例。

相比之下,swagger-ui-dist适用于需要资产为客户端服务的服务器端项目。该模块在导入时包含一个absolutePath辅助函数,该函数返回swagger-ui-dist模块安装位置的绝对文件系统路径。

注意:我们建议swagger-ui在您的工具允许时使用,因为这swagger-ui-dist 会导致更多的代码通过线路。

该模块的内容反映了dist您在 Git 存储库中看到的文件夹。最有用的文件是swagger-ui-bundle.js,它是 Swagger UI 的构建,其中包含在一个文件中运行所需的所有代码。该文件夹还有一个index.html资产,可以轻松地为 Swagger UI 提供服务,如下所示:

const express = require('express')
const pathToSwaggerUi = require('swagger-ui-dist').absolutePath()
const app = express()
app.use(express.static(pathToSwaggerUi))
app.listen(3000)

该模块还导出SwaggerUIBundleand SwaggerUIStandalonePreset,因此如果您在无法处理传统 npm 模块的 JavaScript 项目中,您可以执行以下操作:

var SwaggerUIBundle = require('swagger-ui-dist').SwaggerUIBundle
const ui = SwaggerUIBundle({
    url: "https://petstore.swagger.io/v2/swagger.json",
    dom_id: '#swagger-ui',
    presets: [
      SwaggerUIBundle.presets.apis,
      SwaggerUIBundle.SwaggerUIStandalonePreset
    ],
    layout: "StandaloneLayout"
  })

SwaggerUIBundle相当于SwaggerUI

Docker

您可以直接从 Docker Hub 中提取 swagger-ui 的预构建 docker 镜像:

docker pull swaggerapi/swagger-uidocker run -p 80:8080 swaggerapi/swagger-ui

将在端口 80 上使用 Swagger UI 启动 nginx。

或者你可以在你的主机上提供你自己的 swagger.json

docker run -p 80:8080 -e SWAGGER_JSON=/foo/swagger.json -v /bar:/foo swaggerapi/swagger-ui

可以通过指定BASE_URL环境变量来更改 Web 应用程序的基本 URL :

docker run -p 80:8080 -e BASE_URL=/swagger -e SWAGGER_JSON=/foo/swagger.json -v /bar:/foo swaggerapi/swagger-ui

这将在/swagger而不是/.

有关通过 Docker 映像控制 Swagger UI 的更多信息,请参阅配置文档的 Docker 部分。

解包

您可以使用 unpkg 的界面将 Swagger UI 的代码直接嵌入到您的 HTML 中:

<script src="https://unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js" charset="UTF-8"></script>
<!-- `SwaggerUIBundle` is now available on the page -->

有关如何使用 unpkg 的更多信息,请参阅unpkg 的主页

没有 HTTP 或 HTML 的静态文件

一旦 swagger-ui 成功生成了/dist目录,您就可以将其复制到您自己的文件系统和主机。

普通的旧 HTML/CSS/JS(独立)

该文件夹/dist包含在静态网站或 CMS 上运行 SwaggerUI 所需的所有 HTML、CSS 和 JS 文件,无需 NPM。

  1. 下载最新版本
  2. /dist文件夹的内容复制到您的服务器。
  3. index.html在您的 HTML 编辑器中打开并将“https://petstore.swagger.io/v2/swagger.json”替换为您的 OpenAPI 3.0 规范的 URL。

Swagger Codegen 文档

Swagger Codegen 是一个开源代码生成器,用于直接从 Swagger 定义的 RESTful API 构建服务器存根和客户端 SDK。Swagger Codegen 的源代码可以在 GitHub 中找到。

GitHub: https://github.com/swagger-api/swagger-codegen

兼容性

Swagger Codegen 版本 发布日期 Swagger 规范兼容性 笔记
2.3.0(即将发布的小版本) 待定 1.0, 1.1, 1.2, 2.0 具有重大更改的次要版本
2.2.2(即将发布补丁) 待定 1.0, 1.1, 1.2, 2.0 补丁发布(无中断更改)
2.2.1(电流稳定) 2016-08-07 1.0, 1.1, 1.2, 2.0 标签 v2.2.1
2.1.6 2016-04-06 1.0, 1.1, 1.2, 2.0 标签 v2.1.6
2.0.17 2014-08-22 1.1、1.2 标签 v2.0.17
1.0.4 2012-04-12 1.0、1.1 标签 v1.0.4

安装

先决条件

在下载和运行 Swagger Codegen 之前,需要在您的计算机上安装以下依赖项。

  • Java,版本 7 或更高版本

使用 Homebrew 安装

如果您有 Mac 或 Linux 环境,那么您可以使用 Homebrew 安装 Swagger Codegen。

brew install swagger-codegen

从 Maven 中心安装

Swagger Codegen 项目的所有版本都可以在Maven Central上找到 。 访问 Maven 上的这个文件夹,并选择合适的版本(我们推荐最新版本)。

您可以下载并运行可执行的 .jar 文件(例如, swagger-codegen-cli-2.2.1.jar

或者,您也可以使用 wget 命令。

wget {link address of the executable .jar file}

例子:

wget https://oss.sonatype.org/content/repositories/releases/io/swagger/swagger-codegen-cli/2.2.1/swagger-codegen-cli-2.2.1.jar

用法

为简单起见,我们假设您已安装 swagger-codegen-cli-2.2.1 。请访问 Swagger Codegen 的安装部分,了解如何在您的机器上安装 Codegen。

支持的语言列表

要获取 Swagger Codegen 支持的语言列表 -

如果您安装了 Homebrew:

swagger-codegen

否则,您可以使用:

java -jar swagger-codegen-cli-2.2.1.jar
终端中的帮助选项

要查看 Swagger Codegen 的各种帮助部分选项 -

如果您安装了 Homebrew:

swagger-codegen help

否则,您可以使用:

java -jar swagger-codegen-cli-2.2.1.jar help

获得各种帮助部分选项后,您就可以了解特定主题。

如果您安装了 Homebrew:

swagger-codegen help <command>

例子:

swagger-codegen help generate

否则,您可以使用:

java -jar swagger-codegen-cli-2.2.1.jar help <command>

例子:

java -jar swagger-codegen-cli-2.2.1.jar help generate

要查看 Swagger Codegen 支持的特定语言的各种配置帮助部分选项 -

如果您安装了 Homebrew:

swagger-codegen config-help -l <language name>

例子:

swagger-codegen config-help -l php

否则,您可以使用:

java -jar swagger-codegen-cli-2.2.1.jar config-help -l <language name>

例子:

java -jar swagger-codegen-cli-2.2.1.jar config-help -l php
生成代码

从现有的 swagger 规范生成代码 -

如果您安装了 Homebrew:

swagger-codegen generate -i <path of your Swagger specification> -l <language>

例子:

swagger-codegen generate -i http://petstore.swagger.io/v2/swagger.json -l csharp

否则,您可以使用:

java -jar swagger-codegen-cli-2.2.1.jar generate -i <path of your Swagger specification> -l <language> ` 示例:

java -jar swagger-codegen-cli-2.2.1.jar generate -i http://petstore.swagger.io/v2/swagger.json -l csharp

在上面的代码中,我们传递了两个参数 : - i-l-i 用于指定 API 规范的路径。 -l 用于指定您要为您指定的 API 规范生成代码的语言

Codegen 创建一个 README 文件,其中包含运行和构建 API 的所有信息。每种语言都会创建不同的 README,因此请仔细阅读以了解如何构建 Swagger 定义的 API。

OpenAPI Guide

什么是 OpenAPI?

OpenAPI 规范(以前称为 Swagger 规范)是 REST API 的 API 描述格式。OpenAPI 文件允许您描述整个 API,包括:

  • 可用端点 ( /users) 和每个端点上的操作 ( GET /users, POST /users)
  • 操作参数 每个操作的输入和输出
  • 认证方法
  • 联系信息、许可、使用条款和其他信息。

API 规范可以用 YAML 或 JSON 编写。这种格式对人和机器都易于学习和阅读。完整的 OpenAPI 规范可以在 GitHub 上找到:OpenAPI 3.0 规范

什么是 Swagger?

Swagger是一组围绕 OpenAPI 规范构建的开源工具,可帮助您设计、构建、记录和使用 REST API。主要的 Swagger 工具包括:

  • Swagger Editor – 基于浏览器的编辑器,您可以在其中编写 OpenAPI 规范。
  • Swagger UI – 将 OpenAPI 规范呈现为交互式 API 文档。
  • Swagger Codegen – 根据 OpenAPI 规范生成服务器存根和客户端库。

为什么要使用 OpenAPI?

API 描述其自身结构的能力是 OpenAPI 中所有令人敬畏的根源。编写完成后,OpenAPI 规范和 Swagger 工具可以通过多种方式进一步推动您的 API 开发:

  • 设计为先的用户:使用扬鞭代码生成生成服务器存根为你的API。唯一剩下的就是实现服务器逻辑——您的 API 已经准备好上线了!
  • 使用扬鞭代码生成,以生成客户端库为您的API超过40种语言。
  • 使用Swagger UI生成交互式 API 文档,让您的用户可以直接在浏览器中尝试 API 调用。
  • 使用规范将 API 相关工具连接到您的 API。例如,将规范导入SoapUI以创建 API 的自动化测试。
  • 和更多!查看与 Swagger 集成的开源商业工具

基本结构

您可以在YAMLJSON 中编写 OpenAPI 定义。在本指南中,我们仅使用 YAML 示例,但 JSON 也同样有效。用 YAML 编写的示例 OpenAPI 3.0 定义如下所示:

openapi: 3.0.0
info:
  title: Sample API
  description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
  version: 0.1.9
servers:
  - url: http://api.example.com/v1
    description: Optional server description, e.g. Main (production) server
  - url: http://staging-api.example.com
    description: Optional server description, e.g. Internal staging server for testing
paths:
  /users:
    get:
      summary: Returns a list of users.
      description: Optional extended description in CommonMark or HTML.
      responses:
        '200':    # status code
          description: A JSON array of user names
          content:
            application/json:
              schema: 
                type: array
                items: 
                  type: string

所有关键字名称都区分大小写

元数据

每个 API 定义都必须包含该定义所基于的 OpenAPI 规范的版本:

openapi: 3.0.0

OpenAPI 版本定义了 API 定义的整体结构——您可以记录什么以及如何记录。OpenAPI 3.0 使用带有三部分版本号的语义版本控制。的可用版本3.0.03.0.13.0.2,和3.0.3; 它们在功能上是相同的。

info部分包含 API 信息:titledescription(可选)version,:

info:
  title: Sample API
  description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
  version: 0.1.9

title是您的 API 名称。description是关于您的 API 的扩展信息。它可以是多行的,并支持Markdown的CommonMark方言以进行富文本表示。在CommonMark提供的范围内支持 HTML(请参阅CommonMark 0.27 规范中的HTML 块)。是指定 API 版本的任意字符串(不要将其与文件修订或版本混淆)。您可以使用诸如Major.minor.patch 之类的语义版本控制,或诸如1.0-beta2017-07-25 之类的任意字符串。 version``openapi``info 还支持用于联系信息、许可、服务条款和其他详细信息的其他关键字。

参考:信息对象

服务器

servers部分指定 API 服务器和基本 URL。您可以定义一台或多台服务器,例如生产和沙箱。

servers:
  - url: http://api.example.com/v1
    description: Optional server description, e.g. Main (production) server
  - url: http://staging-api.example.com
    description: Optional server description, e.g. Internal staging server for testing

所有 API 路径都相对于服务器 URL。在上面的示例中,/users表示http://api.example.com/v1/usershttp://staging-api.example.com/users,具体取决于所使用的服务器。有关更多信息,请参阅API 服务器和基本路径

路径

paths部分定义了 API 中的各个端点(路径),以及这些端点支持的 HTTP 方法(操作)。例如,GET /users可以描述为:

paths:
  /users:
    get:
      summary: Returns a list of users.
      description: Optional extended description in CommonMark or HTML
      responses:
        '200':
          description: A JSON array of user names
          content:
            application/json:
              schema: 
                type: array
                items: 
                  type: string

操作定义包括参数、请求正文(如果有)、可能的响应状态代码(例如 200 OK 或 404 Not Found)和响应内容。有关更多信息,请参阅路径和操作

参数

操作可以通过 URL 路径 ( /users/{userId})、查询字符串 ( /users?role=admin)、标头 ( X-CustomHeader: Value) 或 cookie ( Cookie: debug=0)传递参数。您可以定义参数数据类型、格式、它们是必需的还是可选的,以及其他详细信息:

paths:
  /users/{userId}:
    get:
      summary: Returns a user by ID.
      parameters:
        - name: userId
          in: path
          required: true
          description: Parameter description in CommonMark or HTML.
          schema:
            type : integer
            format: int64
            minimum: 1
      responses: 
        '200':
          description: OK

有关更多信息,请参阅描述参数

请求正文

如果操作发送请求正文,则使用requestBody关键字描述正文内容和媒体类型。

paths:
  /users:
    post:
      summary: Creates a user.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                username:
                  type: string
      responses: 
        '201':
          description: Created

有关更多信息,请参阅描述请求正文

回应

对于每个操作,您可以定义可能的状态代码,例如 200 OK 或 404 Not Found,以及响应正文schema。模式可以内联定义或通过$ref. 您还可以为不同的内容类型提供示例响应:

paths:
  /users/{userId}:
    get:
      summary: Returns a user by ID.
      parameters:
        - name: userId
          in: path
          required: true
          description: The ID of the user to return.
          schema:
            type: integer
            format: int64
            minimum: 1
      responses:
        '200':
          description: A user object.
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: integer
                    format: int64
                    example: 4
                  name:
                    type: string
                    example: Jessica Smith
        '400':
          description: The specified user ID is invalid (not a number).
        '404':
          description: A user with the specified ID was not found.
        default:
          description: Unexpected error

请注意,响应 HTTP 状态代码必须用引号括起来:“200”(OpenAPI 2.0 不需要这样做)。有关更多信息,请参阅描述响应

输入和输出模型

globalcomponents/schemas 部分允许您定义 API 中使用的通用数据结构。它们可以在需要$ref时通过a进行引用schema——在参数、请求主体和响应主体中。例如,这个 JSON 对象:

{
  "id": 4,
  "name": "Arthur Dent"
}

可以表示为:

components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
          example: 4
        name:
          type: string
          example: Arthur Dent
      # Both properties are required
      required:  
        - id
        - name

然后在请求正文架构和响应正文架构中引用如下:

paths:
  /users/{userId}:
    get:
      summary: Returns a user by ID.
      parameters:
        - in: path
          name: userId
          required: true
          schema:
            type: integer
            format: int64
            minimum: 1
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'    # <-------
  /users:
    post:
      summary: Creates a new user.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/User'      # <-------
      responses:
        '201':
          description: Created

验证

securitySchemessecurity关键字是用来描述你的API中使用的身份验证方法。

components:
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
security:
  - BasicAuth: []

支持的身份验证方法有:

有关更多信息,请参阅身份验证

完整规格

完整的 OpenAPI 3.0 规范可在 GitHub 上获得:https : //github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md

API Server and Base URL

所有 API 端点都相对于基本 URL。例如,假设基本 URL 为https://api.example.com/v1/users端点指的是 https://api.example.com/v1/users

https://api.example.com/v1/users?role=admin&status=active
\________________________/\____/ \______________________/
         server URL       endpoint    query parameters
                            path

在 OpenAPI 3.0 中,您可以使用servers数组为 API 指定一个或多个基本 URL。servers替换OpenAPI 2.0 中使用的host,basePathschemes关键字。每个服务器都有一个url和一个可选的 Markdown 格式的description.

servers:
  - url: https://api.example.com/v1    # The "url: " prefix is required

您还可以拥有多个服务器,例如生产和沙箱:

servers:
  - url: https://api.example.com/v1
    description: Production server (uses live data)
  - url: https://sandbox-api.example.com:8443/v1
    description: Sandbox server (uses test data)

服务器 URL 格式

服务器 URL 格式遵循RFC 3986,通常如下所示:

scheme://host[:port][/path]

主机可以是名称或 IP 地址(IPv4 或 IPv6)。OpenAPI 3.0 也支持来自 OpenAPI 2.0 的WebSocket 方案ws://wss://。有效服务器 URL 的示例:

https://api.example.com
https://api.example.com:8443/v1/reports
http://localhost:3025/v1
http://10.0.81.36/v1
ws://api.example.com/v1
wss://api.example.com/v1
/v1/reports
/
//api.example.com

如果服务器 URL 是相对的,则会针对托管给定 OpenAPI 定义文件的服务器进行解析(更多内容见下文)。注意:服务器 URL 不得包含查询字符串参数。例如,这是无效的:

https://api.example.com/v1?route=

如果servers数组未提供或为空,则服务器 URL 默认为/

servers:
  - url: /

服务器模板

服务器 URL 的任何部分——方案、主机名或其部分、端口、子路径——都可以使用变量进行参数化。变量由服务器 url 中的 {大括号} 表示,如下所示:

servers:
  - url: https://{customerId}.saas-app.com:{port}/v2
    variables:
      customerId:
        default: demo
        description: Customer ID assigned by the service provider
      port:
        enum:
          - '443'
          - '8443'
        default: '443'

路径参数不同,服务器变量不使用schema. 相反,它们被假定为字符串。变量可以具有任意值,也可以限制为enum. 在任何情况下,default都需要一个值,如果客户端不提供值,将使用该值。变量description是可选的,但对于富文本格式具有并支持 Markdown ( CommonMark )很有用。服务器模板的常见用例:

  • 指定多个协议(例如 HTTP 与 HTTPS)。
  • SaaS(托管)应用程序,其中每个客户都有自己的子域。
  • 不同地理区域的区域服务器(例如:Amazon Web Services)。
  • SaaS 和内部部署 API 的单一 API 定义。

例子

HTTPS 和 HTTP
servers:
  - url: http://api.example.com
  - url: https://api.example.com

或者使用模板:

servers:
  - url: '{protocol}://api.example.com'
    variables:
      protocol:
        enum:
          - http
          - https
        default: https

注意:这两个示例在语义上是不同的。第二个示例将 HTTPS 服务器显式设置为default,而第一个示例没有默认服务器。

制作、开发和分期
servers:
  - url: https://{environment}.example.com/v2
    variables:
      environment:
        default: api    # Production server
        enum:
          - api         # Production server
          - api.dev     # Development server
          - api.staging # Staging server
SaaS 和内部部署
servers:
  - url: '{server}/v1'
    variables:
      server:
        default: https://api.example.com  # SaaS server
不同地理区域的区域端点
servers:
  - url: https://{region}.api.cognitive.microsoft.com
    variables:
      region:
        default: westus
        enum:
          - westus
          - eastus2
          - westcentralus
          - westeurope
          - southeastasia

覆盖服务器

全局servers数组可以在路径级别或操作级别被覆盖。如果某些端点使用与 API 的其余部分不同的服务器或基本路径,这会很方便。常见的例子有:

  • 文件上传和下载操作的不同基本 URL,
  • 已弃用但仍可使用的端点。
servers:
  - url: https://api.example.com/v1
paths:
  /files:
    description: File upload and download operations
    servers:
      - url: https://files.example.com
        description: Override base path for all operations with the /files path
    ...
  /ping:
    get:
      servers:
        - url: https://echo.example.com
          description: Override base path for the GET /ping operation

相对 URL

servers数组中 的 URL可以是相对的,例如/v2. 在这种情况下,根据托管给定 OpenAPI 定义的服务器解析 URL。这对于托管在客户自己的服务器上的本地安装很有用。例如,如果托管在的定义http://localhost:3001/openapi.yaml指定url: /v2url则解析为http://localhost:3001/v2。相对 URL 解析规则遵循RFC 3986。此外,API 定义中的几乎所有其他 URL,包括 OAuth 2 流端点termsOfService、外部文档 URL 等,都可以相对于服务器 URL 进行指定。

servers:
  - url: https://api.example.com
  - url: https://sandbox-api.example.com
# Relative URL to Terms of Service
info:
  version: 0.0.0
  title: test
  termsOfService: /terms-of-use
# Relative URL to external documentation
externalDocs:
  url: /docs
  description: Find more info here
# Relative URLs to OAuth2 authorization and token URLs
components:
  securitySchemes:
    oauth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: /oauth/dialog
          tokenUrl: /oauth/token

请注意,如果使用多个服务器,则相对 URL 指定的资源应该存在于所有服务器上。

媒体类型

媒体类型是请求或响应正文数据的格式。Web 服务操作可以接受和返回不同格式的数据,最常见的是 JSON、XML 和图像。您可以在请求和响应定义中指定媒体类型。下面是一个响应定义的例子:

paths:
  /employees:
    get:
      summary: Returns a list of employees.
      responses:
        '200':      # Response
          description: OK
          content:  # Response body
            application/json:  # Media type
              schema:          # Must-have
                type: object   # Data type
                properties: 
                  id:
                    type: integer
                  name:
                    type: string
                  fullTime: 
                    type: boolean
                example:       # Sample data
                    id: 1
                    name: Jessica Right
                    fullTime: true

responses我们下面有个人反应的定义。如您所见,每个响应都由其代码定义('200'在我们的示例中)。content代码下方的关键字对应于响应正文。一种或多种媒体类型作为该content关键字的子关键字。每种媒体类型都包括一个schema,定义消息体的数据类型,以及一个或多个示例(可选)。有关定义正文数据的更多信息,请参阅定义请求正文和定义响应

媒体类型名称

content字段下方列出的媒体类型应符合RFC 6838。例如,您可以使用标准类型或特定于供应商的类型(由 表示.vnd) –

application/json
application/xml
application/x-www-form-urlencoded
multipart/form-data
text/plain; charset=utf-8
text/html
application/pdf
image/png
application/vnd.mycompany.myapp.v2+json
application/vnd.ms-excel
application/vnd.openstreetmap.data+xml
application/vnd.github-issue.text+json
application/vnd.github.v3.diff
image/vnd.djvu

多种媒体类型

您可能需要指定多种媒体类型:

paths:
  /employees:
    get:
      summary: Returns a list of employees.
      responses:
        '200':      # Response
          description: OK
          content:  # Response body
            application/json:   # One of media types
              schema:
                type: object
                properties:
                  id:
                    type: integer
                  name:
                    type: string
                  fullTime: 
                    type: boolean
            application/xml:    # Another media types
              schema:
                type: object
                properties:
                  id:
                    type: integer
                  name:
                    type: string
                  fullTime: 
                    type: boolean

要对多种媒体类型使用相同的数据格式components,请在规范的部分定义一个自定义对象,然后在每个媒体类型中引用此对象:

paths:
  /employees:
    get:
      responses:
        '200':      # Response
          description: OK
          content:  # Response body
            application/json:  # Media type
             schema: 
               $ref: '#/components/schemas/Employee'    # Reference to object definition
            application/xml:   # Media type
             schema: 
               $ref: '#/components/schemas/Employee'    # Reference to object definition
components:
  schemas:
    Employee:      # Object definition
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        fullTime: 
          type: boolean

要定义多种媒体类型相同的格式,你也可以使用占位符喜欢*/*application/*image/*或其他:

paths:
  /info/logo:
    get:
      responses:
        '200':           # Response
          description: OK
          content:       # Response body
            image/*:     # Media type
             schema: 
               type: string
               format: binary

您用作媒体类型的值(image/*在我们的示例中)与您在HTTP 请求和响应的AcceptContent-Type标头中看到的非常相似。不要混淆占位符和AcceptContent-Type标头的实际值。例如,image/*响应正文的占位符意味着服务器将对与占位符匹配的所有响应使用相同的数据结构。这并不意味着字符串image/*将在Content-Type标题中指定。的Content-Type报头最有可能将具有图像/ PNG图像/ JPEG,或一些其他类似的值。

路径和操作

在 OpenAPI 术语中,路径是API 公开的端点(资源),例如/users/reports/summary/,而操作是用于操作这些路径的 HTTP 方法,例如 GET、POST 或 DELETE。

路径

API 路径和操作paths在 API 规范的全局部分中定义。

paths:
  /ping:
    ...
  /users:
    ...
  /users/{id}:
    ...

所有路径都相对于API 服务器 URL。完整的请求 URL 构造为<server-url>/path. servers也可以在路径级别或操作级别覆盖全局(更多内容见下文)。出于文档目的,路径可能有一个可选的短summary和长description。此信息应该与此路径中的所有操作相关。description可以是多行的,并且支持Markdown (CommonMark) 进行富文本表示。

paths:
  /users/{id}:
    summary: Represents a user
    description: >
      This resource represents an individual user in the system.
      Each user is identified by a numeric `id`.
    get:
      ...
    patch:
      ...
    delete:
      ...

路径模板

您可以使用花括号{}将 URL 的一部分标记为路径参数

/users/{id}
/organizations/{orgId}/members/{memberId}
/report.{format}

API 客户端在进行 API 调用时需要提供适当的参数值,例如/users/5/users/12

操作

对于每个路径,您定义可用于访问该路径的操作(HTTP 方法)。OpenAPI的3.0支持getpostputpatchdeleteheadoptions,和trace。单个路径可以支持多个操作,例如GET /users获取用户列表和POST /users添加新用户。OpenAPI 将唯一操作定义为路径和 HTTP 方法的组合。这意味着不允许对同一路径使用两个 GET 或两个 POST 方法——即使它们具有不同的参数(参数对唯一性没有影响)。下面是一个操作的最小示例:

paths:
  /ping:
    get:
      responses:
        '200':
          description: OK

这是带有参数和响应架构的更详细示例:

paths:
  /users/{id}:
    get:
      tags:
        - Users
      summary: Gets a user by ID.
      description: >
        A detailed description of the operation.
        Use markdown for rich text representation,
        such as **bold**, *italic*, and [links](https://swagger.io).
      operationId: getUserById
      parameters:
        - name: id
          in: path
          description: User ID
          required: true
          schema:
            type: integer
            format: int64
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
      externalDocs:
        description: Learn more about user operations provided by this API.
        url: http://api.example.com/docs/user-operations/
components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
      required:
        - id
        - name

操作还支持一些用于文档目的的可选元素:

  • summary和长description的什么样的操作一样。description可以是多行的,并且支持Markdown (CommonMark) 进行富文本表示。
  • tags– 用于按资源或任何其他限定符对操作进行逻辑分组。请参阅使用标签对操作进行分组
  • externalDocs – 用于引用包含附加文档的外部资源。

操作参数

OpenAPI 3.0 支持通过路径、查询字符串、标头和 cookie 传递的操作参数。您还可以为将数据传输到服务器的操作定义请求主体,例如 POST、PUT 和 PATCH。有关详细信息,请参阅描述参数描述请求正文

路径中的查询字符串

查询字符串参数不得包含在路径中。它们应该被定义为查询参数

不正确:

paths:
  /users?role={role}:

正确的:

paths:
  /users:
    get:
      parameters:
        - in: query
          name: role
          schema:
            type: string
            enum: [user, poweruser, admin]
          required: true

这也意味着不可能有多个仅在查询字符串不同的路径,例如:

GET /users?firstName=value&lastName=value
GET /users?role=value

这是因为 OpenAPI 将唯一操作视为路径和 HTTP 方法的组合,附加参数不会使操作唯一。相反,您应该使用唯一的路径,例如:

GET /users/findByName?firstName=value&lastName=value
GET /users/findByRole?role=value

操作编号

operationId是用于标识操作的可选唯一字符串。如果提供,这些 ID 在您的 API 中描述的所有操作中必须是唯一的。

/users:
  get:
    operationId: getUsers
    summary: Gets all users
    ...
  post:
    operationId: addUser
    summary: Adds a new user
    ...
/user/{id}:
  get:
    operationId: getUserById
    summary: Gets a user by user ID
    ...

operationId 的一些常见用例是:

  • 某些代码生成器使用此值来命名代码中的相应方法。
  • 链接可以通过 引用链接操作operationId

弃用的操作

您可以将特定操作标记为deprecated指示它们应停止使用:

/pet/findByTags:
  get:
    deprecated: true

工具可以以特定方式处理已弃用的操作。例如,Swagger UI 以不同的样式显示它们:

Swagger UI 中已弃用的操作

覆盖全局服务器

全局servers数组可以在路径级别或操作级别被覆盖。如果某些端点使用与 API 的其余部分不同的服务器或基本路径,这将非常有用。常见的例子有:

  • 文件上传和下载操作的不同基本 URL。
  • 已弃用但仍可使用的端点。
servers:
  - url: https://api.example.com/v1
paths:
  /files:
    description: File upload and download operations
    servers:
      - url: https://files.example.com
        description: Override base path for all operations with the /files path
    ...
  /ping:
    get:
      servers:
        - url: https://echo.example.com
          description: Override base path for the GET /ping operation

描述参数

在 OpenAPI 3.0 中,参数在parameters操作或路径的部分中定义。要描述参数,请指定其name、位置 ( in)、数据类型(由schema或定义content)和其他属性,例如descriptionrequired。下面是一个例子:

paths:
  /users/{userId}:
    get:
      summary: Get a user by ID
      parameters:
        - in: path
          name: userId
          schema:
            type: integer
          required: true
          description: Numeric ID of the user to get

请注意,这parameters是一个数组,因此,在 YAML 中,每个参数定义都必须-在其前面列出一个破折号 ( )。

参数类型

OpenAPI 3.0 根据参数位置区分以下参数类型。位置由参数的in键确定,例如,in: queryin: path

路径参数

路径参数是 URL 路径的可变部分。它们通常用于指向集合中的特定资源,例如由 ID 标识的用户。一个 URL 可以有多个路径参数,每个参数都用大括号 表示{ }

GET /users/{id}
GET /cars/{carId}/drivers/{driverId}
GET /report.{format}

当客户端进行 API 调用时,每个路径参数都必须替换为实际值。在 OpenAPI 中,路径参数是使用in: path. 参数名称必须与路径中指定的名称相同。还记得添加 required: true,因为路径参数总是需要的。例如,/users/{id}端点将被描述为:

paths:
  /users/{id}:
    get:
      parameters:
        - in: path
          name: id   # Note the name is the same as in the path
          required: true
          schema:
            type: integer
            minimum: 1
          description: The user ID

包含数组和对象的路径参数可以用不同的方式序列化:

  • 路径样式扩展(矩阵)——以分号为前缀,例如 /map/point;x=50;y=20
  • 标签扩展——以点为前缀,例如 /color.R=100.G=200.B=150
  • simple-style – 逗号分隔,例如 /users/12,34,56

序列化方法由styleexplode关键字指定。要了解更多信息,请参阅参数序列化

查询参数

查询参数是最常见的参数类型。它们出现在请求 URL 末尾的问号 ( ?) 之后,不同的name=value对由与号 ( )分隔&。查询参数可以是必需的,也可以是可选的。

GET /pets/findByStatus?status=available
GET /notes?offset=100&limit=50

使用in: query来表示的查询参数:

parameters:
        - in: query
          name: offset
          schema:
            type: integer
          description: The number of items to skip before starting to collect the result set
        - in: query
          name: limit
          schema:
            type: integer
          description: The numbers of items to return

注意:要描述作为查询参数传递的 API 密钥,请使用securitySchemessecurity代替。请参阅API 密钥

查询参数可以是原始值、数组和对象。OpenAPI 3.0 提供了多种方法来序列化查询字符串中的对象和数组。

数组可以序列化为:

  • form/products?color=blue,green,red/products?color=blue&color=green,取决于explode关键字
  • spaceDelimited(与collectionFormat: ssvOpenAPI 2.0相同)——/products?color=blue%20green%20red
  • pipeDelimited(与collectionFormat: pipesOpenAPI 2.0相同)——/products?color=blue|green|red

对象可以序列化为:

  • form/points?color=R,100,G,200,B,150/points?R=100&G=200&B=150,取决于explode关键字
  • deepObject —— /points?color[R]=100&color[G]=200&color[B]=150

序列化方法由styleexplode关键字指定。要了解更多信息,请参阅参数序列化

查询参数中的保留字符

RFC 3986定义了一组:/?#[]@!$&'()*+,;=用作 URI 组件分隔符的保留字符。当需要在查询参数值中按字面使用这些字符时,它们通常是百分比编码的。例如,/被编码为%2F (或 %2f),因此参数值quotes/h2g2.txt将被发送为

GET /file?path=quotes%2Fh2g2.txt

如果您想要一个不是百分比编码的查询参数,请添加allowReserved: true到参数定义中:

parameters:
        - in: query
          name: path
          required: true
          schema:
            type: string
          allowReserved: true    # <-----

在这种情况下,参数值将像这样发送:

GET /file?path=quotes/h2g2.txt

标题参数

API 调用可能需要使用 HTTP 请求发送自定义标头。OpenAPI 允许您将自定义请求标头定义为in: header参数。例如,假设调用GET /ping需要X-Request-ID标头:

GET /ping HTTP/1.1
Host: example.com
X-Request-ID: 77e1c83b-7bb0-437b-bc50-a7a58e5660ac

使用 OpenAPI 3.0,您可以按如下方式定义此操作:

paths:
  /ping:
    get:
      summary: Checks if the server is alive
      parameters:
        - in: header
          name: X-Request-ID
          schema:
            type: string
            format: uuid
          required: true

以类似的方式,您可以定义自定义响应标头。标头参数可以是基元、数组和对象。数组和对象使用simple样式进行序列化。有关更多信息,请参阅参数序列化

注意:头参数命名为AcceptContent-TypeAuthorization是不允许的。要描述这些标头,请使用相应的 OpenAPI 关键字:

标题 OpenAPI 关键字 有关更多信息,请参阅…
Content-Type 请求内容类型:requestBody.content.<media-type> 响应内容类型:responses.<code>.content.<media-type> 描述请求正文描述响应媒体类型
Accept responses.<code>.content.<media-type> 描述响应, 媒体类型
Authorization securitySchemes, security 验证

操作还可以在Cookie标头中传递参数,如Cookie: name=value. 多个 cookie 参数在同一个标头中发送,用分号和空格分隔。

GET /api/users
Host: example.com
Cookie: debug=0; csrftoken=BUSe35dohU3O1MZvDCUOJ

使用in: cookie定义的cookie参数:

parameters:
        - in: cookie
          name: debug
          schema:
            type: integer
            enum: [0, 1]
            default: 0
        - in: cookie
          name: csrftoken
          schema:
            type: string

Cookie 参数可以是原始值、数组和对象。数组和对象使用form样式进行序列化。有关更多信息,请参阅参数序列化

注意:要定义 cookie 身份验证,请改用API 密钥

必需和可选参数

默认情况下,OpenAPI 将所有请求参数视为可选参数。您可以required: true根据需要添加以标记参数。请注意,路径参数必须有required: true,因为它们始终是必需的。

parameters:
        - in: path
          name: userId
          schema:
            type: integer
          required: true    # <----------
          description: Numeric ID of the user to get.

模式与内容

要描述参数内容,可以使用schemacontent关键字。它们是互斥的,用于不同的场景。在大多数情况下,您会使用schema. 它允许您描述原始值,以及序列化为字符串的简单数组和对象。数组和对象参数的序列化方法由该参数中使用的关键字styleexplode关键字定义。

parameters:
  - in: query
    name: color
    schema:
      type: array
      items:
        type: string
    # Serialize as color=blue,black,brown (default)
    style: form
    explode: false

content用于style和未涵盖的复杂序列化场景explode。例如,如果您需要在查询字符串中发送一个 JSON 字符串,如下所示:

filter={"type":"t-shirt","color":"blue"}

在这种情况下,您需要将参数包装schemacontent/<media-type>如下所示。在schema定义了参数的数据结构,和媒体类型(在本例- application/json)用作到描述串行化格式的外部规范的参考。

parameters:
  - in: query
    name: filter

    # Wrap 'schema' into 'content.<media-type>'
    content:
      application/json:  # <---- media type indicates how to serialize / deserialize the parameter content
        schema:
          type: object
          properties:
            type:
              type: string
            color:
              type: string

Swagger UI 和 Swagger Editor 用户注意事项:content Swagger UI 3.23.7+ 和 Swagger Editor 3.6.34+ 支持参数。

默认参数值

使用default参数架构中的关键字来指定可选参数的默认值。如果客户端未在请求中提供参数值,则默认值是服务器使用的值。值类型必须与参数的数据类型相同。一个典型的例子是分页参数,例如offsetlimit

GET /users
GET /users?offset=30&limit=10

假设offset默认值为 0,limit默认值为 20,范围从 0 到 100,您可以将这些参数定义为:

parameters:
        - in: query
          name: offset
          schema:
            type: integer
            minimum: 0
            default: 0
          required: false
          description: The number of items to skip before starting to collect the result set.
        - in: query
          name: limit
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
          required: false
          description: The number of items to return.

常见错误

使用default关键字时有两个常见错误:

  • 使用defaultrequired参数或特性,例如,与路径参数。这没有意义——如果需要一个值,客户端必须始终发送它,并且从不使用默认值。
  • 使用default指定的样本值。这不是预期用途,default并且可能导致某些 Swagger 工具出现意外行为。为此,请使用exampleorexamples关键字。请参阅添加示例

枚举参数

您可以通过将enum参数添加到参数的schema. 枚举值必须与参数数据类型具有相同的类型。

parameters:
        - in: query
          name: status
          schema:
            type: string
            enum:
              - available
              - pending
              - sold

更多信息:定义一个 Enum

常数参数

您可以将常量参数定义为仅具有一个可能值的必需参数:

parameters:
        - in: query
          name: rel_date
          required: true
          schema:
            type: string
            enum:
              - now

enum属性指定可能的值。在此示例中,只能使用一个值,这将是 Swagger UI 中可供用户选择的唯一值。

注意:常量参数与默认参数值不同。一个常量参数总是由客户端发送,而如果参数不是由客户端发送,则默认值是服务器使用的值。

空值和可空参数

查询字符串参数可能只有名称而没有值,如下所示:

GET /foo?metadata

使用allowEmptyValue来形容这样的参数:

parameters:
        - in: query
          name: metadata
          schema:
            type: boolean
          allowEmptyValue: true  # <-----

OpenAPI 3.0 还支持nullablein 模式,允许操作参数具有null值。例如,以下模式对应int?于 C# 和java.lang.IntegerJava:

schema:
            type: integer
            format: int32
            nullable: true

注意: nullable与可选参数或空值参数不同。nullable表示参数值可以是null。具体实现可能会选择将一个不存在或空值的参数映射到null,但严格来说这些不是一回事。

参数示例

您可以为参数指定一个example或多个examples。示例值应与参数架构匹配。单例:

parameters:
        - in: query
          name: limit
          schema:
            type: integer
            minimum: 1
          example: 20

多个命名示例:

parameters:
        - in: query
          name: ids
          description: One or more IDs
          required: true
          schema:
            type: array
            items:
              type: integer
          style: form
          explode: false
          examples:
            oneId:
              summary: Example of a single ID
              value: [5]   # ?ids=5
            multipleIds:
              summary: Example of multiple IDs
              value: [1, 5, 7]   # ?ids=1,5,7

有关详细信息,请参阅添加示例

弃用的参数

用于deprecated: true将参数标记为已弃用。

- in: query
          name: format
          required: true
          schema:
            type: string
            enum: [json, xml, yaml]
          deprecated: true
          description: Deprecated, use the appropriate `Accept` header instead.

常用参数

路径所有方法的通用参数

路径的所有操作共享的参数可以在路径级别而不是操作级别定义。路径级参数由该路径的所有操作继承。一个典型的用例是操作通过路径参数访问的资源的 GET/PUT/PATCH/DELETE 操作。

paths:
  /user/{id}:
    parameters:
      - in: path
        name: id
        schema:
          type: integer
        required: true
        description: The user ID
    get:
      summary: Gets a user by ID
      ...
    patch:
      summary: Updates an existing user with the specified ID
      ...
    delete:
      summary: Deletes the user with the specified ID
      ...

在操作级别定义的任何额外参数都与路径级别参数一起使用:

paths:
  /users/{id}:
    parameters:
      - in: path
        name: id
        schema:
          type: integer
        required: true
        description: The user ID.
    # GET/users/{id}?metadata=true
    get:
      summary: Gets a user by ID
      # Note we only define the query parameter, because the {id} is defined at the path level.
      parameters:
        - in: query
          name: metadata
          schema:
            type: boolean
          required: false
          description: If true, the endpoint returns only the user metadata.
      responses:
        '200':
          description: OK

特定的路径级参数可以在操作级被覆盖,但不能被删除。

paths:
  /users/{id}:
    parameters:
      - in: path
        name: id
        schema:
          type: integer
        required: true
        description: The user ID.
    # DELETE /users/{id} - uses a single ID.
    # Reuses the {id} parameter definition from the path level.
    delete:
      summary: Deletes the user with the specified ID.
      responses:
        '204':
          description: User was deleted.
    # GET /users/id1,id2,id3 - uses one or more user IDs.
    # Overrides the path-level {id} parameter.
    get:
      summary: Gets one or more users by ID.
      parameters:
        - in: path
          name: id
          required: true
          description: A comma-separated list of user IDs.
          schema:
            type: array
            items:
              type: integer
            minItems: 1
          explode: false
          style: simple
      responses:
        '200':
          description: OK

各种路径的通用参数

不同的API路径可能有共同的参数,比如分页参数。您可以在全局components部分的参数下定义通用参数,并通过$ref.

components:
  parameters:
    offsetParam:  # <-- Arbitrary name for the definition that will be used to refer to it.
                  # Not necessarily the same as the parameter name.
      in: query
      name: offset
      required: false
      schema:
        type: integer
        minimum: 0
      description: The number of items to skip before starting to collect the result set.
    limitParam:
      in: query
      name: limit
      required: false
      schema:
        type: integer
        minimum: 1
        maximum: 50
        default: 20
      description: The numbers of items to return.
paths:
  /users:
    get:
      summary: Gets a list of users.
      parameters:
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
      responses:
        '200':
          description: OK
  /teams:
    get:
      summary: Gets a list of teams.
      parameters:
        - $ref: '#/components/parameters/offsetParam'
        - $ref: '#/components/parameters/limitParam'
      responses:
        '200':
          description: OK

请注意,中定义的参数components不是应用于所有操作的参数——它们只是可以轻松重用的全局定义。

参数依赖

OpenAPI 3.0 不支持参数依赖和互斥参数。https://github.com/OAI/OpenAPI-Specification/issues/256 上有一个开放功能请求。您可以做的是记录参数描述中的限制并定义 400 Bad Request 响应中的逻辑。例如,考虑/report接受相对日期范围 ( rdate) 或精确范围 ( start_date+ end_date)的端点:

GET /report?rdate=Today
GET /report?start_date=2016-11-15&end_date=2016-11-20

您可以按如下方式描述此端点:

paths:
  /report:
    get:
      parameters:
        - name: rdate
          in: query
          schema:
            type: string
          description: >
             A relative date range for the report, such as `Today` or `LastWeek`.
             For an exact range, use `start_date` and `end_date` instead.
        - name: start_date
          in: query
          schema:
            type: string
            format: date
          description: >
            The start date for the report. Must be used together with `end_date`.
            This parameter is incompatible with `rdate`.
        - name: end_date
          in: query
          schema:
            type: string
            format: date
          description: >
            The end date for the report. Must be used together with `start_date`.
            This parameter is incompatible with `rdate`.
      responses:
        '400':
          description: Either `rdate` or `start_date`+`end_date` are required.

参数序列化

序列化意味着将数据结构或对象状态转换为以后可以传输和重构的格式。OpenAPI 3.0 支持操作参数(路径、查询、标头和 cookie)中的数组和对象,并允许您指定这些参数的序列化方式。序列化方法由styleexplode关键字定义:

  • style定义如何分隔多个值。可能的样式取决于参数位置 - pathqueryheadercookie
  • explode (true/false) 指定数组和对象是否应为每个数组项或对象属性生成单独的参数。

OpenAPI 序列化规则基于RFC 6570定义的 URI 模板模式的子集。工具实现者可以使用现有的 URI 模板库来处理序列化,如下所述

路径参数

路径参数支持以下style值:

  • 简单-(默认)逗号分隔值。对应于{param_name}URI 模板。
  • label – 点前缀值,也称为标签扩展。对应于{.param_name}URI 模板。
  • 矩阵– 以分号为前缀的值,也称为路径样式扩展。对应于{;param_name}URI 模板。

默认的序列化方法是style: simpleand explode: false。给定 path /users/{id}, path 参数id序列化如下:

风格 爆炸 URI模板 原始值 id = 5 数组 ID = [3, 4, 5] 对象 id = {“role”: “admin”, “firstName”: “Alex”}
简单* 假* /用户/{id} /用户/5 /用户/3,4,5 /用户/角色,管理员,名字,亚历克斯
简单的 真的 /users/{id*} /用户/5 /用户/3,4,5 /users/role=admin,firstName=Alex
标签 错误的 /users/{.id} /用户/.5 /用户/.3,4,5 /users/.role,admin,firstName,Alex
标签 真的 /users/{.id*} /用户/.5 /用户/.3.4.5 /users/.role=admin.firstName=亚历克斯
矩阵 错误的 /users/{;id} /users/;id=5 /users/;id=3,4,5 /users/;id=role,admin,firstName,Alex
矩阵 真的 /users/{;id*} /users/;id=5 /users/;id=3;id=4;id=5 /users/;role=admin;firstName=Alex

*默认序列化方法

labelmatrix样式有时与局部路径参数,如所用/users{id}的,因为参数值获得前缀。

查询参数

查询参数支持以下style值:

  • form –(默认)与号分隔的值,也称为表单样式的查询扩展。对应于{?param_name}URI 模板。
  • spaceDelimited – 以空格分隔的数组值。与collectionFormat: ssvOpenAPI 2.0相同。仅对非分解数组 ( explode: false) 有效,也就是说,如果数组是单个参数,则空格分隔数组值,如arr=a b c
  • pipeDelimited – 管道分隔的数组值。与collectionFormat: pipesOpenAPI 2.0相同。仅对非分解数组 ( explode: false) 有效,也就是说,如果数组是单个参数,则管道将数组值分开,如arr=a|b|c.
  • deepObject – 一种使用表单参数渲染嵌套对象的简单方法(仅适用于对象)。

默认的序列化方法是style: formand explode: true。这对应 collectionFormat: multi 于 OpenAPI 2.0。给定/users带有查询参数的路径id,查询字符串序列化如下:

风格 爆炸 URI模板 原始值 id = 5 数组 ID = [3, 4, 5] 对象 id = {“role”: “admin”, “firstName”: “Alex”}
表格* 真* /用户{?id*} /users?id=5 /users?id=3&id=4&id=5 /users?role=admin&firstName=Alex
形式 错误的 /用户{?id} /users?id=5 /users?id=3,4,5 /users?id=role,admin,firstName,Alex
空格分隔 真的 /用户{?id*} 不适用 /users?id=3&id=4&id=5 不适用
空格分隔 错误的 不适用 不适用 /users?id=3%204%205 不适用
管道分隔 真的 /用户{?id*} 不适用 /users?id=3&id=4&id=5 不适用
管道分隔 错误的 不适用 不适用 /users?id=3|4|5 不适用
深对象 真的 不适用 不适用 不适用 /users?id[role]=admin&id[firstName]=Alex

*默认序列化方法

此外,该allowReserved关键字指定:/?#[]@!$&'()*+,;=参数值中的保留字符是允许按原样发送,还是应该进行百分比编码。默认情况下,allowReservedisfalse和保留字符是百分比编码的。例如,/被编码为%2F(或%2f),因此参数值quotes/h2g2.txt将被发送为quotes%2Fh2g2.txt

标题参数

标题参数始终使用simple样式,即逗号分隔值。这对应于{param_name}URI 模板。可选explode关键字控制对象序列化。给定名为 的请求标头X-MyHeader,标头值序列化如下:

风格 爆炸 URI模板 原始值 X-MyHeader = 5 数组 X-MyHeader = [3, 4, 5] Object X-MyHeader = {“role”: “admin”, “firstName”: “Alex”}
简单* 假* {ID} X-MyHeader:5 X-MyHeader:3,4,5 X-MyHeader:角色、管理员、名字、亚历克斯
简单的 真的 {ID*} X-MyHeader:5 X-MyHeader:3,4,5 X-MyHeader: role=admin,firstName=Alex

*默认序列化方法

Cookie 参数始终使用该form样式。可选explode关键字控制数组和对象序列化。给定名为 的 cookie id,cookie 值按如下方式序列化:

风格 爆炸 URI模板 原始值 id = 5 数组 ID = [3, 4, 5] 对象 id = {“role”: “admin”, “firstName”: “Alex”}
表格* 真* 饼干:id=5
形式 错误的 id={id} 饼干:id=5 曲奇:id=3,4,5 Cookie: id=role,admin,firstName,Alex

*默认序列化方法

序列化和 RFC 6570

OpenAPI 序列化规则基于RFC 6570定义的 URI 模板子集。工具实现者可以使用现有的 URI 模板库来处理序列化。您将需要根据路径和参数定义构建 URI 模板。下表显示了 OpenAPI 关键字如何映射到 URI 模板修饰符。

关键词 URI 模板修饰符
style: simple 没有任何
style: label . 字首
style: matrix ; 字首
style: form ?&前缀(取决于查询字符串中的参数位置)
style: pipeDelimited ?&前缀(取决于查询字符串中的参数位置)——但使用管道`
style: spaceDelimited ?&前缀(取决于查询字符串中的参数位置)——但使用空格而不是逗号,来连接数组值
explode: false 没有任何
explode: true * 后缀
allowReserved: false 没有任何
allowReserved: true + 字首

例如,考虑/users{id}带有查询参数的路径metadata,定义如下:

paths:
  # /users;id=3;id=4?metadata=true
  /users{id}:
    get:
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: array
            items:
              type: integer
            minItems: 1
          style: matrix
          explode: true
        - in: query
          name: metadata
          schema:
            type: boolean
          # Using the default serialization for query parameters:
          # style=form, explode=false, allowReserved=false
      responses:
        '200':
          description: A list of users

path 参数id使用matrix带有explode修饰符的样式,它对应于{;id*}模板。查询参数metadata使用默认form样式,与{?metadata}模板相对应。完整的 URI 模板如下所示:

/users{;id*}{?metadata}

然后,客户端应用程序可以使用 URI 模板库根据此模板和特定参数值生成请求 URL。

其他序列化方法

styleexplode涵盖最常见的序列化方法,但不是全部。对于更复杂的场景(例如,查询字符串中的 JSON 格式的对象),您可以使用content关键字并指定定义序列化格式的媒体类型。有关更多信息,请参阅架构与内容

描述请求正文

请求正文通常与“创建”和“更新”操作(POST、PUT、PATCH)一起使用。例如,当使用 POST 或 PUT 创建资源时,请求正文通常包含要创建的资源的表示。OpenAPI 3.0 提供了requestBody描述请求体的关键字。

与 OpenAPI 2.0 的差异

如果您之前使用过 OpenAPI 2.0,以下是帮助您开始使用 OpenAPI 3.0 的更改摘要:

  • 正文和表单参数替换为requestBody.
  • 操作现在可以使用表单数据和其他媒体类型,例如 JSON。
  • consumes数组被替换为将requestBody.content媒体类型映射到其模式的映射。
  • 架构可能因媒体类型而异。
  • anyOf并且oneOf可用于指定替代模式。
  • 表单数据现在可以包含对象,您可以为对象和数组指定序列化策略。
  • GET、DELETE 和 HEAD 不再允许具有请求正文,因为它没有按照RFC 7231定义语义。

requestBody、内容和媒体类型

与 OpenAPI 2.0 使用bodyformData参数定义请求正文不同,OpenAPI 3.0 使用requestBody关键字来区分负载和参数(例如查询字符串)。的requestBody是,它可以让你消耗不同的媒体类型,如JSON,XML,表单数据,纯文本,和其他人,并使用不同的媒体类型不同的架构更加灵活。requestBodycontent对象、可选的Markdown格式description和可选的required标志(false默认情况下)组成。content列出操作使用的媒体类型(例如application/json)并schema为每个媒体类型指定。默认情况下,请求正文是可选的. 要根据需要标记正文,请使用required: true

paths:
  /pets:
    post:
      summary: Add a new pet
      requestBody:
        description: Optional description in *Markdown*
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Pet'
          application/xml:
            schema:
              $ref: '#/components/schemas/Pet'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/PetForm'
          text/plain:
            schema:
              type: string
      responses:
        '201':
          description: Created

content允许通配符媒体类型。例如,image/*代表所有图像类型;*/* 代表所有类型并且在功能上等同于application/octet-stream. 在解释规范时,特定媒体类型优先于通配符媒体类型,例如,image/png> image/*> */*

paths:
  /avatar:
    put:
      summary: Upload an avatar
      requestBody:
        content:
          image/*:    # Can be image/png, image/svg, image/gif, etc.
            schema:
              type: string
              format: binary

anyOf,oneOf

OpenAPI 3.0 支持anyOfoneOf,因此您可以为请求正文指定替代模式:

requestBody:
        description: A JSON object containing pet information
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/Cat'
                - $ref: '#/components/schemas/Dog'
                - $ref: '#/components/schemas/Hamster'

上传文件

要了解如何描述文件上传,请参阅文件上传分段请求

请求正文示例

请求正文可以有一个example或多个examples. exampleexamplesrequestBody.content.<media-type>对象的属性。如果提供,这些示例将覆盖架构提供的示例。这很方便,例如,如果请求和响应使用相同的架构,但您想要不同的示例。example允许单个内联示例:

requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Pet'
            example:
              name: Fluffy
              petType: dog

所述examples(多个)都更灵活-你可以有一个内联例如,$ref参考,或指向包含所述有效负载例如一个外部URL。每个示例也可以有可选的summarydescription用于文档目的。

requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Pet'
            examples:
              dog:  # <--- example name
                summary: An example of a dog
                value:
                  # vv Actual payload goes here vv
                  name: Fluffy
                  petType: dog
              cat:  # <--- example name
                summary: An example of a cat
                externalValue: http://api.example.com/examples/cat.json   # cat.json contains {"name": "Tiger", "petType": "cat"}
              hamster:  # <--- example name
                $ref: '#/components/examples/hamster'
components:
  examples:
    hamster:  # <--- example name
      summary: An example of a hamster
      value:
        # vv Actual payload goes here vv
        name: Ginger
        petType: hamster

有关更多信息,请参阅添加示例

可重复使用的身体

您可以将请求正文定义放在全局components.requestBodies部分中,$ref并将它们放在其他地方。如果多个操作具有相同的请求主体,这很方便——这样您就可以轻松地重用相同的定义。

paths:
  /pets:
    post:
      summary: Add a new pet
      requestBody:
        $ref: '#/components/requestBodies/PetBody'
  /pets/{petId}
    put:
      summary: Update a pet
      parameters: [ ... ]
      requestBody:
        $ref: '#/components/requestBodies/PetBody'
components:
  requestBodies:
    PetBody:
      description: A JSON object containing pet information
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Pet'

表单数据

术语“表单数据”用于媒体类型application/x-www-form-urlencodedmultipart/form-data,它们通常用于提交 HTML 表单。

  • application/x-www-form-urlencoded用于key=value成对发送简单的 ASCII 文本数据。负载格式类似于查询参数
  • multipart/form-data允许在单个消息中提交二进制数据以及多种媒体类型(例如,图像和 JSON)。每个表单字段在带有内部 HTTP 标头的负载中都有自己的部分。multipart请求通常用于文件上传

为了说明表单数据,请考虑一个 HTML POST 表单:

<form action="http://example.com/survey" method="post">
  <input type="text"   name="name" />
  <input type="number" name="fav_number" />
  <input type="submit"/>
</form>

此表单将数据 POST 到表单的端点:

POST /survey HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 28
name=Amy+Smith&fav_number=42

在 OpenAPI 3.0 中,表单数据使用type: object模式建模,其中对象属性代表表单字段:

paths:
  /survey:
    post:
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                name:          # <!--- form field name
                  type: string
                fav_number:    # <!--- form field name
                  type: integer
              required:
                - name
                - email

表单字段可以包含原始值、数组和对象。默认情况下,数组被序列化为array_name=value1&array_name=value2,对象被序列化为prop1=value1&prop=value2,但您可以使用 OpenAPI 3.0 规范定义的其他序列化策略。序列化策略在encoding部分中指定,如下所示:

requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                color:
                  type: array
                  items:
                    type: string
            encoding:
              color:            # color=red,green,blue
                style: form
                explode: false

默认情况下,正文:/?#[]@!$&'()*+,;=中表单字段值中的保留字符在发送时application/x-www-form-urlencoded采用百分比编码。要允许按原样发送这些字符,请使用如下allowReserved关键字:

requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                foo:
                  type: string
                bar:
                  type: string
                baz:
                  type: string
            encoding:
              # Don't percent-encode reserved characters in the values of "bar" and "baz" fields
              bar:
                allowReserved: true
              baz:
                allowReserved: true

key=value可以使用自由格式模式对 任意对进行建模:

requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              additionalProperties: true    # this line is optional

表单数据中的复杂序列化

styleexplode关键字 提供的序列化规则只为具有原始属性的原始数组和对象定义了行为。对于更复杂的场景,例如嵌套数组或表单数据中的JSON,需要使用contentType关键字指定媒体类型,用于对复杂字段的值进行编码。以Slack 传入 webhook为例。消息可以直接作为 JSON 发送,或者 JSON 数据可以在名为payloadso的表单字段中发送(在应用 URL 编码之前):

payload={"text":"Swagger is awesome"}

这可以描述为:

openapi: 3.0.0
info:
  version: 1.0.0
  title: Slack Incoming Webhook
externalDocs:
  url: https://api.slack.com/incoming-webhooks
servers:
  - url: https://hooks.slack.com
paths:
  /services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX:
    post:
      summary: Post a message to Slack
      requestBody:
        content:

          application/json:
            schema:
              $ref: '#/components/schemas/Message'
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                payload:     # <--- form field that contains the JSON message
                  $ref: '#/components/schemas/Message'
            encoding:
              payload:
                contentType: application/json
      responses:
        '200':
          description: OK
components:
  schemas:
    Message:
      title: A Slack message
      type: object
      properties:
        text:
          type: string
          description: Message text
      required:
        - text

参考

请求体对象

媒体类型对象

上传文件

在OpenAPI 3.0中,可以描述直接用请求内容上传的文件和用multipart请求上传的文件。使用requestBody关键字来描述包含文件的请求负载。在 下content,指定请求媒体类型(例如image/pngapplication/octet-stream)。文件使用type: string带有format: binary或的模式format: base64,具体取决于文件内容的编码方式。例如:

requestBody:
  content:
    image/png:
      schema:
        type: string
        format: binary

此定义对应于如下所示的 HTTP 请求:

POST /upload
Host: example.com
Content-Length: 808
Content-Type: image/png
[file content goes there]

通过分段请求上传

要描述与其他数据一起发送的文件,请使用multipart媒体类型。例如:

requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                orderId:
                  type: integer
                userId:
                  type: integer
                fileName:
                  type: string
                  format: binary

相应的 HTTP 请求负载将包括多个部分:

POST /upload
Host: example.com
Content-Length: 2740
Content-Type: multipart/form-data; boundary=abcde12345
--abcde12345
Content-Disposition: form-data; name="orderId"
1195
--abcde12345
Content-Disposition: form-data; name="userId"
545
--abcde12345
Content-Disposition: form-data; name="fileName"; filename="attachment.txt"
Content-Type: text/plain
[file content goes there]
--abcde12345--

多文件上传

使用multipart媒体类型定义上传任意数量的文件(文件数组):

requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                filename:
                  type: array
                  items:
                    type: string
                    format: binary

相应的 HTTP 请求将如下所示:

POST /upload
Host: example.com
Content-Length: 2740
Content-Type: multipart/form-data; boundary=abcde12345
--abcde12345
Content-Disposition: form-data; name="fileName"; filename="file1.txt"
Content-Type: text/plain
[file content goes there]
--abcde12345
Content-Disposition: form-data; name="fileName"; filename="file2.png"
Content-Type: image/png
[file content goes there]
------WebKitFormBoundaryWfPNVh4wuWBlyEyQ
Content-Disposition: form-data; name="fileName"; filename="file3.jpg"
Content-Type: image/jpeg
[file content goes there]
--abcde12345--

参考

有关 OpenAPI 中文件上传的更多信息,请参阅 OpenAPI 3.0 规范的以下部分:

文件上传的注意事项

多部分内容的特殊注意事项

多部分请求

多部分请求将一组或多组数据组合成一个主体,由边界分隔。您通常将这些请求用于文件上传和在单个请求中传输多种类型的数据(例如,文件和 JSON 对象)。在 OpenAPI 3 中,您可以通过以下方式描述多部分请求:

requestBody:
  content: 
    multipart/form-data: # Media type
      schema:            # Request payload
        type: object
        properties:      # Request parts
          id:            # Part 1 (string value)
            type: string
            format: uuid
          address:       # Part2 (object)
            type: object
            properties:
              street:
                type: string
              city:
                type: string
          profileImage:  # Part 3 (an image)
            type: string
            format: binary

你从requestBody/content关键字开始。然后,您指定请求数据的媒体类型。文件上传通常使用*multipart/form-data*媒体类型,混合数据请求通常使用*multipart/mixed*. 在媒体类型下方,放置schema关键字以指示您开始描述请求负载。您将请求的各个部分描述为schema对象的属性。如您所见,多部分请求可以包含各种数据:字符串、JSON 格式的对象和二进制数据。您还可以指定一个或多个文件进行上传。(要了解更多信息,请参阅文件上传。)上面的示例对应于以下请求:

POST /upload HTTP/1.1
Content-Length: 428
Content-Type: multipart/form-data; boundary=abcde12345
--abcde12345
Content-Disposition: form-data; name="id"
Content-Type: text/plain
123e4567-e89b-12d3-a456-426655440000
--abcde12345
Content-Disposition: form-data; name="address"
Content-Type: application/json
{
  "street": "3, Garden St",
  "city": "Hillsbery, UT"
}
--abcde12345
Content-Disposition: form-data; name="profileImage "; filename="image1.png"
Content-Type: application/octet-stream
{…file content…}
--abcde12345--

指定内容类型

默认情况下,Content-Type根据schema描述请求部分的属性类型自动设置各个请求部分的 :

架构属性类型 内容类型
基元或基元数组 text/plain
复数值或复数值数组 application/json
binarybase64格式的字符串 application/octet-stream

Content-Type为请求部分设置特定,请使用该字段。您添加为媒体类型属性的子级,与所在的级别相同。在下面的示例中,我们将多部分请求的部分设置为:encoding/*{property-name}*/contentType``encoding``schema``contentType``profileImage``image/png, image/jpg

requestBody:
  content:
    multipart/form-data:
      schema:
        type: object
        properties: # Request parts
          id:
            type: string
            format: uuid
          address:
            type: object
            properties:
              street:
                type: string
              city:
                type: string
          profileImage:
            type: string
            format: base64
      encoding: # The same level as schema
        profileImage: # Property name (see above)
          contentType: image/png, image/jpeg

指定自定义标题

多部分请求的部分通常不使用任何标头,除了Content. 如果您需要包含自定义标题,请使用该字段来描述这些标题(见下文)。有关描述标头的完整信息,请参阅描述参数。以下是为多部分请求的一部分定义的自定义标头示例:encoding/*{property-name}*/headers

requestBody:
  content:
    multipart/form-data:
      schema:
        type: object
        properties:
          id:
            type: string
            format: uuid
          profileImage:
            type: string
            format: binary
      encoding:
        profileImage: # Property name
          contentType: image/png, image/jpeg
          headers: # Custom headers
            X-Custom-Header:
              description: This is a custom header
              schema:
                type: string

此声明符合以下请求:

POST /upload HTTP/1.1
Content-Length: 428
Content-Type: multipart/form-data; boundary=abcde12345
--abcde12345
Content-Disposition: form-data; name="id"
Content-Type: text/plain
123e4567-e89b-12d3-a456-426655440000
--abcde12345
Content-Disposition: form-data; name="profileImage"; filename="image1.png"
Content-Type: image/png
X-Custom-Header: x-header
{…file content…}
--abcde12345--

描述响应

API 规范需要responses为所有 API 操作指定。每个操作必须至少定义一个响应,通常是成功的响应。响应由其 HTTP 状态代码和响应正文和/或标头中返回的数据定义。这是一个最小的例子:

paths:
  /ping:
    get:
      responses:
        '200':
          description: OK
          content:
            text/plain:
              schema:
                type: string
                example: pong

响应媒体类型

API 可以响应各种媒体类型。JSON 是最常见的数据交换格式,但不是唯一可能的格式。要指定响应媒体类型,请content在操作级别使用关键字。

paths:
  /users:
    get:
      summary: Get all users
      responses:
        '200':
          description: A list of users
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ArrayOfUsers'
            application/xml:
              schema:
                $ref: '#/components/schemas/ArrayOfUsers'
            text/plain:
              schema:
                type: string
  # This operation returns image
  /logo:
    get:
      summary: Get the logo image
      responses:
        '200':
          description: Logo image in PNG format
          content:
            image/png:
              schema:
                type: string
                format: binary

更多信息: 媒体类型

HTTP 状态代码

在 下responses,每个响应定义都以状态代码开头,例如 200 或 404。操作通常返回一个成功状态代码和一个或多个错误状态。要定义响应代码的范围,您可以使用以下范围定义:1XX、2XX、3XX、4XX 和 5XX。如果使用显式代码定义响应范围,则显式代码定义优先于该代码的范围定义。每个响应状态都需要一个description. 例如,您可以描述错误响应的条件。Markdown ( CommonMark ) 可用于富文本表示。

responses:
        '200':
          description: OK
        '400':
          description: Bad request. User ID must be an integer and larger than 0.
        '401':
          description: Authorization information is missing or invalid.
        '404':
          description: A user with the specified ID was not found.
        '5XX':
          description: Unexpected error.

请注意,API 规范不一定需要涵盖所有可能的HTTP 响应代码,因为它们可能事先未知。但是,它预计会涵盖成功的响应和任何已知错误。我们所说的“已知错误”是指,例如,对于按 ID 返回资源的操作的 404 Not Found 响应,或在操作参数无效的情况下的 400 Bad Request 响应。

响应体

所述schema关键字被用于描述响应主体。模式可以定义:

  • anobject或 an array— 通常与 JSON 和 XML API 一起使用,
  • 原始数据类型,例如数字或字符串——用于纯文本响应,
  • 一个文件——(见下文)。

可以在操作中内联定义架构:

responses:
        '200':
          description: A User object
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: integer
                    description: The user ID.
                  username:
                    type: string
                    description: The user name.

或在全局components.schemas部分中定义并通过$ref. 如果多种媒体类型使用相同的模式,这很有用。

responses:
        '200':
          description: A User object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
          description: The user ID.
        username:
          type: string
          description: The user name.

返回文件的响应

API 操作可以返回文件,例如图像或 PDF。OpenAPI 3.0 将文件输入/输出内容定义为type: stringwithformat: binaryformat: base64。这与 OpenAPI 2.0 形成对比,后者用于type: file描述文件输入/输出内容。如果响应单独返回文件,您通常会使用二进制字符串模式并为响应指定适当的媒体类型content

paths:
  /report:
    get:
      summary: Returns the report in the PDF format
      responses:
        '200':
          description: A PDF file
          content:
            application/pdf:
              schema:
                type: string
                format: binary

文件也可以作为 base64 编码字符串嵌入到 JSON 或 XML 中。在这种情况下,您将使用以下内容:

paths:
  /users/me:
    get:
      summary: Returns user information
      responses:
        '200':
          description: A JSON object containing user name and avatar
          content:
            application/json:
              schema:
                type: object
                properties:
                  username:
                    type: string
                  avatar:          # <-- image embedded into JSON
                    type: string
                    format: byte
                    description: Base64-encoded contents of the avatar image

oneOf,anyOf

OpenAPI 3.0 还支持oneOfanyOf,因此您可以为响应正文指定替代模式。

responses:
        '200':
          description: A JSON object containing pet information
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Cat'
                  - $ref: '#/components/schemas/Dog'
                  - $ref: '#/components/schemas/Hamster'

空响应体

一些响应,例如 204 No Content,没有正文。要指示响应正文为空,请不要content为响应指定 a :

responses:
        '204':
          description: The resource was deleted successfully.

响应头

来自 API 的响应可以包含自定义标头,以提供有关 API 调用结果的附加信息。例如,限速 API 可以通过响应头提供限速状态,如下所示:

HTTP 1/1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 99
X-RateLimit-Reset: 2016-10-12T11:00:00Z
{ ... }

您可以headers为每个响应定义自定义,如下所示:

paths:
  /ping:
    get:
      summary: Checks if the server is alive.
      responses:
        '200':
          description: OK
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Request limit per hour.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: The number of requests left for the time window.
            X-RateLimit-Reset:
              schema:
                type: string
                format: date-time
              description: The UTC date/time at which the current rate limit window resets.

请注意,目前 OpenAPI 规范不允许为不同的响应代码或不同的 API 操作定义公共响应头。您需要单独定义每个响应的标头。

默认响应

有时,一个操作可能会返回多个具有不同 HTTP 状态代码的错误,但它们都具有相同的响应结构:

responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        # These two error responses have the same schema
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

您可以使用default响应来共同描述这些错误,而不是单独描述这些错误。“默认”表示此响应用于所有未单独用于此操作的 HTTP 代码。

responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        # Definition of all error statuses
        default:
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

重用响应

如果多个操作返回相同的响应(状态代码和数据),您可以responses在全局components对象的部分中定义它,然后通过$ref在操作级别引用该定义。这对于具有相同状态代码和响应正文的错误响应很有用。

paths:
  /users:
    get:
      summary: Gets a list of users.
      response:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ArrayOfUsers'
        '401':
          $ref: '#/components/responses/Unauthorized'   # <-----
  /users/{id}:
    get:
      summary: Gets a user by ID.
      response:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '401':
          $ref: '#/components/responses/Unauthorized'   # <-----
        '404':
          $ref: '#/components/responses/NotFound'       # <-----
# Descriptions of common components
components:
  responses:
    NotFound:
      description: The specified resource was not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Unauthorized
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  schemas:
    # Schema for error response body
    Error:
      type: object
      properties:
        code:
          type: string
        message:
          type: string
      required:
        - code
        - message

请注意,中定义的响应components.responses不会自动应用于所有操作。这些只是可以被多个操作引用和重用的定义。

将响应值链接到其他操作

响应中的某些值可以用作其他操作的参数。一个典型的例子是“创建资源”操作,它返回创建的资源的 ID,这个 ID 可用于获取该资源、更新或删除它。OpenAPI 3.0 提供了links关键字来描述响应和其他 API 调用之间的这种关系。有关更多信息,请参阅链接

常问问题

我可以根据请求参数有不同的响应吗?如:

GET /something -> {200, schema_1}
GET /something?foo=bar -> {200, schema_2}

在 OpenAPI 3.0 中,您可以使用oneOf为响应指定替代模式,并在响应中口头记录可能的依赖关系description。但是,无法将特定模式链接到特定参数组合。

参考

响应对象

媒体类型对象

组件对象

数据模型(模式)

OpenAPI 3.0 数据类型基于扩展子集JSON 模式规范 Wright Draft 00(又名 Draft 5)。数据类型使用Schema 对象进行描述。要了解如何对各种数据类型进行建模,请参阅以下主题:

添加示例

您可以向参数、属性和对象添加示例,以使您的 Web 服务的 OpenAPI 规范更加清晰。以某种方式处理您的 API 的工具和库可以读取示例。例如,API 模拟工具可以使用示例值来生成模拟请求。您可以为对象、单个属性和操作参数指定示例。要指定示例,请使用exampleexamples键。详情请见下文。

Swagger UI 用户注意事项:examples自 Swagger UI 3.23.0 和 Swagger Editor 3.6.31 起支持多个。

注意:不要将示例值与默认值混淆。一个例子说明了该值应该是什么。如果客户端不提供该值,则默认值是服务器使用的值。

参数示例

下面是一个参数值的例子:

parameters:
  - in: query
    name: status
    schema:
      type: string
      enum: [approved, pending, closed, new]
      example: approved     # Example of a parameter value

参数的多个示例:

parameters:
  - in: query
    name: limit
    schema:
      type: integer
      maximum: 50
    examples:       # Multiple examples
      zero:         # Distinct name
        value: 0    # Example value
        summary: A sample limit value  # Optional description
      max: # Distinct name
        value: 50   # Example value
        summary: A sample limit value  # Optional description

如您所见,每个示例都有一个不同的键名。此外,在上面的代码中,我们使用了summary带有描述的可选键。注意:您指定的示例值应与参数数据类型匹配。

请求和响应正文示例

这是example请求正文中关键字的示例:

paths:
  /users:
    post:
      summary: Adds a new user
      requestBody:
        content:
          application/json:
            schema:      # Request body contents
              type: object
              properties:
                id:
                  type: integer
                name:
                  type: string
              example:   # Sample object
                id: 10
                name: Jessica Smith
      responses:
        '200':
          description: OK

请注意,在上面的代码中,exampleschema. 如果schema引用该components部分中定义的某个对象,那么您应该创建examplemedia type 关键字的子项:

paths:
  /users:
    post:
      summary: Adds a new user
      requestBody:
        content:
          application/json:    # Media type
            schema:            # Request body contents
              $ref: '#/components/schemas/User'   # Reference to an object
            example:           # Child of media type because we use $ref above
              # Properties of a referenced object
              id: 10
              name: Jessica Smith
      responses:
        '200':
          description: OK

这是必需的,因为会$ref覆盖它旁边的所有兄弟姐妹。如果需要,您可以使用多个示例:

paths:
  /users:
    post:
      summary: Adds a new user
      requestBody:
        content:
          application/json:     # Media type
            schema:             # Request body contents
              $ref: '#/components/schemas/User'   # Reference to an object
            examples:    # Child of media type
              Jessica:   # Example 1
                value:
                  id: 10
                  name: Jessica Smith
              Ron:       # Example 2
                value:
                  id: 11
                  name: Ron Stewart
      responses:
        '200':
          description: OK

以下是example响应正文的示例:

responses:
  '200':
    description: A user object.
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/User'   # Reference to an object
        example: 
          # Properties of the referenced object
          id: 10
          name: Jessica Smith

响应体中的多个示例:

responses:
  '200':
    description: A user object.
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/User'   # Reference to an object
        examples:
          Jessica:
            value:
              id: 10
              name: Jessica Smith
          Ron:
            value:
              id: 20
              name: Ron Stewart

注意:响应和请求正文中的示例是自由格式的,但应与正文模式兼容。

对象和属性示例

您还可以为该components部分中的对象和各个属性指定示例。

  • 属性级示例:

    components:
      schemas:
        User:    # Schema name
          type: object
          properties:
            id:
              type: integer
              format: int64
              example: 1          # Property example
            name:
              type: string
              example: New order  # Property example
  • 对象级示例:

    components:
      schemas:
        User:       # Schema name
          type: object
          properties:
            id:
              type: integer
            name:
              type: string
          example:   # Object-level example
            id: 1
            name: Jessica Smith

请注意,模式和属性支持单个example但不支持多个examples.

数组示例

您可以添加单个数组项的示例:

components:
  schemas:
    ArrayOfInt:
      type: array
      items:
        type: integer
        format: int64
        example: 1

或包含多个项目的数组级示例:

components:
  schemas:
    ArrayOfInt:
      type: array
      items:
        type: integer
        format: int64
      example: [1, 2, 3]

如果数组包含对象,则可以指定多项示例,如下所示:

components:
  schemas:
    ArrayOfUsers:
      type: array
      items:
        type: object
        properties:
          id:
            type: integer
          name:
            type: string
      example:
        - id: 10
          name: Jessica Smith
        - id: 20
          name: Ron Stewart

请注意,数组和数组项支持单个example但不支持多个examples

XML 和 HTML 数据示例

要描述无法以 JSON 或 YAML 格式呈现的示例值,请将其指定为字符串:

content:
  application/xml:
    schema:
      $ref: '#/components/schemas/xml'
    examples:
      xml:
        summary: A sample XML response
        value: '<objects><object><id>1</id><name>new</name></object><object><id>2</id></object></objects>'
  text/html:
    schema:
      type: string
    examples:
      html:
        summary: A list containing two items
        value: '<html><body><ul><li>item 1</li><li>item 2</li></ul></body></html>'

您可以在此 Stack Overflow 帖子中找到有关在 YAML 中编写多行字符串的信息:https : //stackoverflow.com/questions/3790454/in-yaml-how-do-i-break-a-string-over-multiple-lines

外部例子

如果由于某种原因无法将示例值插入到您的规范中,例如,它既不符合 YAML 规范,也不符合 JSON 规范,您可以使用externalValue关键字来指定示例值的 URL。URL 应指向包含文字示例内容(例如,对象、文件或图像)的资源:

content:
  application/json:
    schema:
      $ref: '#/components/schemas/MyObject'
    examples:
      jsonObject:
        summary: A sample object
        externalValue: 'http://example.com/examples/object-example.json'
  application/pdf:
    schema:
      type: string
      format: binary
    examples:
      sampleFile:
        summary: A sample file
        externalValue: 'http://example.com/examples/example.pdf'

重用示例

您可以在components/examples 规范的部分中定义常见示例,然后在各种参数描述、请求和响应正文描述、对象和属性中重新使用它们:

content:
  application/json:
    schema:
      $ref: '#/components/schemas/MyObject'
    examples:
      objectExample:
        $ref: '#/components/examples/objectExample'
...
components:
  examples:
    objectExample:
      value:
        id: 1
        name: new object
      summary: A sample object

认证和授权

OpenAPI 使用术语安全方案来表示身份验证和授权方案。OpenAPI 3.0 允许您描述使用以下安全方案保护的 API:

按照上面的链接获取有关特定安全类型的指南,或继续阅读以了解如何概括描述安全性。

来自 OpenAPI 2.0 的变化

如果您之前使用过 OpenAPI 2.0,以下是帮助您开始使用 OpenAPI 3.0 的更改摘要:

  • securityDefinitions被重命名为securitySchemes并移动到里面components
  • type: basic被替换为type: httpscheme: basic
  • newtype: http是所有HTTP安全方案的伞型,包括Basic、Bearer等,scheme关键字表示方案类型。
  • 现在可以发送 API 密钥in: cookie
  • 添加了对 OpenID Connect Discovery ( type: openIdConnect) 的支持。
  • OAuth 2 安全方案现在可以定义多个flows.
  • OAuth 2 流程已重命名以匹配OAuth 2 规范accessCode现在authorizationCodeapplication现在clientCredentials

描述安全

使用securitySchemessecurity关键字描述安全性。您用于securitySchemes定义 API 支持的所有安全方案,然后用于security将特定方案应用于整个 API 或单个操作。

步骤 1. 定义 securitySchemes

API 使用的所有安全方案都必须在全局components/securitySchemes部分中定义。本节包含命名安全方案的列表,其中每个方案可以是type

安全方案所需的其他属性取决于type. 以下示例显示了如何定义各种安全方案。在基本验证BearerAuth名称和其他人将被用来指从规范等地这些定义任意名称。

components:
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
    BearerAuth:
      type: http
      scheme: bearer
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
    OpenID:
      type: openIdConnect
      openIdConnectUrl: https://example.com/.well-known/openid-configuration
    OAuth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://example.com/oauth/authorize
          tokenUrl: https://example.com/oauth/token
          scopes:
            read: Grants read access
            write: Grants write access
            admin: Grants access to admin operations

步骤 2. 应用安全性

在该securitySchemes部分定义安全方案后,您可以通过security分别在根级别或操作级别添加该部分来将它们应用于整个 API 或单个操作。在根级别使用时security,除非在操作级别被覆盖,否则将指定的安全方案全局应用于所有 API 操作。在以下示例中,可以使用 API 密钥或 OAuth 2 对 API 调用进行身份验证。ApiKeyAuthOAuth2名称指的是之前在 中定义的方案securitySchemes

security:
  - ApiKeyAuth: []
  - OAuth2:
      - read
      - write
# The syntax is:
# - scheme name:
#     - scope 1
#     - scope 2

对于每个方案,您指定 API 调用所需的安全范围列表(见下文)。范围仅用于 OAuth 2 和 OpenID Connect Discovery;其他安全方案[]改为使用空数组。security可以在单个操作中覆盖全局以使用不同的身份验证类型、不同的 OAuth/OpenID 范围或根本不进行身份验证:

paths:
  /billing_info:
    get:
      summary: Gets the account billing info
      security:
        - OAuth2: [admin]   # Use OAuth with a different scope
      responses:
        '200':
          description: OK
        '401':
          description: Not authenticated
        '403':
          description: Access token does not have the required scope
  /ping:
    get:
      summary: Checks if the server is running
      security: []   # No security
      responses:
        '200':
          description: Server is up and running
        default:
          description: Something is wrong

范围

OAuth 2 和 OpenID Connect 使用范围来控制对各种用户资源的权限。例如,宠物商店的范围可能包括read_petswrite_petsread_orderswrite_ordersadmin。申请时security,OAuth 2 和 OpenID Connect 对应的条目需要指定特定操作(如果security在操作级别使用)或所有 API 调用(如果security在根级别使用)所需的范围列表。

security:
  - OAuth2:
      - scope1
      - scope2
  - OpenId:
      - scopeA
      - scopeB
  - BasicAuth: []
  • 在 OAuth 2 的情况下,使用的范围security必须事先在securitySchemes.
  • 对于 OpenID Connect Discovery,可能的范围在 指定的发现端点中列出openIdConnectUrl
  • 其他方案(Basic、Bearer、API 密钥等)不使用范围,因此它们的security条目指定一个空数组[]

不同的操作通常需要不同的范围,例如读取、写入和管理。在这种情况下,您应该将作用域security应用于特定操作,而不是全局执行。

# Instead of this:
# security:
#   - OAuth2:
#       - read
#       - write
# Do this:
paths:
  /users:
    get:
      summary: Get a list of users
      security:
        - OAuth2: [read]     # <------
      ...
    post:
      summary: Add a user
      security:
        - OAuth2: [write]    # <------
      ...

使用多种身份验证类型

某些 REST API 支持多种身份验证类型。该security部分允许您使用逻辑 OR 和 AND 组合安全要求以实现所需的结果。security使用以下逻辑:

security:    # A OR B
  - A
  - B
security:    # A AND B
  - A
    B
security:    # (A AND B) OR (C AND D)
  - A
    B
  - C
    D

也就是说,security是一个哈希映射数组,其中每个哈希映射包含一个或多个命名的安全方案。哈希图中的项目使用逻辑 AND 组合,数组项目使用逻辑 OR 组合。通过 OR 组合的安全方案是替代方案——任何一种都可以在给定的上下文中使用。通过 AND 组合的安全方案必须在同一请求中同时使用。在这里,我们可以使用基本身份验证或 API 密钥:

security:
  - basicAuth: []
  - apiKey: []

这里,API 要求在请求中包含一对 API 密钥:

security:
  - apiKey1: []
    apiKey2: []

在这里,我们可以使用 OAuth 2 或一对 API 密钥:

security:
  - oauth2: [scope1, scope2]
  - apiKey1: []
    apiKey2: []

参考

安全方案对象

安全需求对象

基本认证

基本身份验证是一种内置于 HTTP 协议中的简单身份验证方案。客户端发送 HTTP 请求,Authorization头部包含单词Basicword 后跟一个空格和一个 base64 编码的字符串username:password。例如,授权为demo / p@55w0rd客户端将发送

Authorization: Basic ZGVtbzpwQDU1dzByZA==

注意:因为 base64 很容易解码,所以基本身份验证只能与其他安全机制(例如 HTTPS/SSL)一起使用。

描述基本身份验证

使用 OpenAPI 3.0,您可以将基本身份验证描述如下:

openapi: 3.0.0
...
components:
  securitySchemes:
    basicAuth:     # <-- arbitrary name for the security scheme
      type: http
      scheme: basic
security:
  - basicAuth: []  # <-- use the same name here

第一部分securitySchemes定义了一个名为basicAuth(任意名称)的安全方案。这个方案必须有type: httpscheme: basicsecurity然后,该部分将基本身份验证应用于整个 API。方括号[]表示使用的安全范围;该列表为空,因为基本身份验证不使用范围。security可以全局设置(如上例所示)或操作级别。如果只有一部分操作需要基本身份验证,则后者很有用:

paths:
  /something:
    get:
      security:
        - basicAuth: []

基本身份验证还可以与其他身份验证方法结合使用,如使用多种身份验证类型中所述

401响应

您还可以定义为缺少凭据或凭据不正确的请求返回的 401“未授权”响应。此响应包含WWW-Authenticate您可能想要提及的标头。与其他常见响应一样,401 响应可以在全局components/responses部分中定义并通过$ref.

paths:
  /something:
    get:
      ...
      responses:
        ...
        '401':
           $ref: '#/components/responses/UnauthorizedError'
    post:
      ...
      responses:
        ...
        '401':
          $ref: '#/components/responses/UnauthorizedError'
...
components:
  responses:
    UnauthorizedError:
      description: Authentication information is missing or invalid
      headers:
        WWW_Authenticate:
          schema:
            type: string

要了解有关responses语法的更多信息,请参阅描述响应

API 密钥

一些 API 使用 API 密钥进行授权。API 密钥是客户端在进行 API 调用时提供的令牌。可以在查询字符串中发送密钥:

GET /something?api_key=abcdef12345

或作为请求标头:

GET /something HTTP/1.1
X-API-Key: abcdef12345

或作为cookie

GET /something HTTP/1.1
Cookie: X-API-KEY=abcdef12345

API 密钥应该是只有客户端和服务器知道的秘密。与Basic authentication一样 ,基于 API 密钥的身份验证仅在与其他安全机制(例如 HTTPS/SSL)一起使用时才被认为是安全的。

描述 API 密钥

在 OpenAPI 3.0 中,API 密钥描述如下:

openapi: 3.0.0
...
# 1) Define the key name and location
components:
  securitySchemes:
    ApiKeyAuth:        # arbitrary name for the security scheme
      type: apiKey
      in: header       # can be "header", "query" or "cookie"
      name: X-API-KEY  # name of the header, query parameter or cookie
# 2) Apply the API key globally to all operations
security:
  - ApiKeyAuth: []     # use the same name as under securitySchemes

此示例定义了一个名为X-API-Key作为请求标头发送的 API 密钥X-API-Key: <key>。密钥名称ApiKeyAuth是安全方案的任意名称(不要与由密钥指定的 API 密钥名称混淆name)。部分中再次使用名称ApiKeyAuthsecurity将此安全方案应用于 API。注意:securitySchemes仅此部分是不够的;您还必须使用securityAPI 密钥才能生效。security也可以在操作级别而不是全局设置。如果只有一部分操作需要 API 密钥,这很有用:

paths:
  /something:
    get:
      # Operation-specific security:
      security:
        - ApiKeyAuth: []
      responses:
        '200':
          description: OK (successfully authenticated)

请注意,可以在一个 API 中支持多种授权类型。请参阅使用多种身份验证类型

多个 API 密钥

某些 API 使用一对安全密钥,例如 API Key 和 App ID。要指定键一起使用(如在逻辑 AND 中),请将它们列在数组中的同一数组项中security

components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: X-API-KEY
    appId:
      type: apiKey
      in: header
      name: X-APP-ID
security:
  - apiKey: []
    appId:  []   # <-- no leading dash (-)

请注意与以下内容的区别:

security:
  - apiKey: []
  - appId:  []

这意味着可以使用任一键(如逻辑 OR)。有关更多示例,请参阅使用多种身份验证类型

401响应

您可以定义为缺少 API 密钥或 API 密钥无效的请求返回的 401“未授权”响应。此响应包含WWW-Authenticate您可能想要提及的标头。与其他常见响应一样,401 响应可以在全局components/responses部分中定义并通过$ref.

paths:
  /something:
    get:
      ...
      responses:
        ...
        '401':
           $ref: "#/components/responses/UnauthorizedError"
    post:
      ...
      responses:
        ...
        '401':
          $ref: "#/components/responses/UnauthorizedError"
components:
  responses:
    UnauthorizedError:
      description: API key is missing or invalid
      headers:
        WWW_Authenticate:
          schema:
            type: string

要了解有关描述响应的更多信息,请参阅描述响应

承载认证

不记名身份验证(也称为令牌身份验证)是一种HTTP 身份验证方案,它涉及称为不记名令牌的安全令牌。“Bearer authentication”这个名字可以理解为“给这个token的持有者提供访问权”。不记名令牌是一个神秘的字符串,通常由服务器响应登录请求而生成。Authorization向受保护资源发出请求时,客户端必须在标头中发送此令牌:

Authorization: Bearer <token>

承载认证方案被作为部分最初创建的OAuth 2.0RFC 6750,但有时也用自身。与Basic authentication类似,Bearer 身份验证只能通过 HTTPS (SSL) 使用。

描述承载认证

在 OpenAPI 3.0 中,承载身份验证是一种带有type: http和的安全方案scheme: bearer。您首先需要在 下定义安全方案components/securitySchemes,然后使用security关键字将此方案应用于所需的范围 - 全局(如下例所示)或特定操作:

openapi: 3.0.0
...
# 1) Define the security scheme type (HTTP bearer)
components:
  securitySchemes:
    bearerAuth:            # arbitrary name for the security scheme
      type: http
      scheme: bearer
      bearerFormat: JWT    # optional, arbitrary value for documentation purposes
# 2) Apply the security globally to all operations
security:
  - bearerAuth: []         # use the same name as above

可选bearerFormat是一个任意字符串,用于指定不记名令牌的格式。由于不记名令牌通常由服务器生成,bearerFormat因此主要用于文档目的,作为对客户端的提示。在上面的例子中,它是“JWT”,意思是JSON Web Token 。方括号[]bearerAuth:[]包含范围所需的API调用的安全问题列表。该列表为空,因为范围仅用于 OAuth 2 和OpenID Connect。在上面的示例中,Bearer 身份验证全局应用于整个 API。如果您只需要将其应用于少数操作,请添加security操作级别而不是全局执行此操作:

paths:
  /something:
    get:
      security:
        - bearerAuth: []

承载身份验证还可以与其他身份验证方法结合使用,如使用多种身份验证类型中所述

401响应

您还可以定义为不包含正确承载令牌的请求返回的 401“未授权”响应。由于 401 响应将被多个操作使用,您可以在全局components/responses部分定义它并通过$ref.

paths:
  /something:
    get:
      ...
      responses:
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        ...
    post:
      ...
      responses:
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        ...
components:
  responses:
    UnauthorizedError:
      description: Access token is missing or invalid

OAuth 2.0

OpenID Connect Discovery

链接

链接是 OpenAPI 3.0 的新特性之一。使用链接,您可以描述一个操作返回的各种值如何用作其他操作的输入。这样,链接提供了操作之间的已知关系和遍历机制。链接的概念有点类似于超媒体,但 OpenAPI 链接不需要实际响应中存在的链接信息。

何时使用链接?

考虑“创建用户”操作:

POST /users HTTP/1.1
Host: example.com
Content-Type: application/json
{
  "name": "Alex",
  "age": 27
}

它返回创建的用户的 ID:

HTTP/1.1 201 Created
Content-Type: application/json
{
  "id": 305
}

然后可以使用此用户 ID 读取、更新或删除用户:、和。使用链接,您可以指定“创建用户”返回的值可以用作“获取用户”、“更新用户”和“删除用户”的参数。另一个例子是通过游标进行分页,其中响应包括一个游标来检索下一个数据集:GET /users/305``PATCH /users/305``DELETE /users/305``id

GET /items?limit=100
 ⇩
{
  "metadata": {
    "previous": null,
    "next": "Q1MjAwNz",
    "count": 10
  },
  ...
}
 ⇩
GET /items?cursor=Q1MjAwNz&limit=100

但是,链接关系不一定在同一资源内,甚至不一定在同一 API 规范内。

定义链接

链接在links每个响应的部分中定义:

responses:
        '200':
          description: Created
          content:
            ...
          links:   # <----
            ...
        '400':
          description: Bad request
          content:
            ...
          links:   # <----
            ...

为了更好地理解这一点,让我们看一个完整的例子。该API定义了“创建用户”和“获取用户”操作,“创建用户”的结果作为“获取用户”的输入。

openapi: 3.0.0
info:
  version: 0.0.0
  title: Links example
paths:
  /users:
    post:
      summary: Creates a user and returns the user ID
      operationId: createUser
      requestBody:
        required: true
        description: A JSON object that contains the user name and age.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/User'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: integer
                    format: int64
                    description: ID of the created user.
          # -----------------------------------------------------
          # Links
          # -----------------------------------------------------
          links:
            GetUserByUserId:   # <---- arbitrary name for the link
              operationId: getUser
              # or
              # operationRef: '#/paths/~1users~1{userId}/get'
              parameters:
                userId: '$response.body#/id'
              description: >
                The `id` value returned in the response can be used as
                the `userId` parameter in `GET /users/{userId}`.
          # -----------------------------------------------------
  /users/{userId}:
    get:
      summary: Gets a user by ID
      operationId: getUser
      parameters:
        - in: path
          name: userId
          required: true
          schema:
            type: integer
            format: int64
      responses:
        '200':
          description: A User object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
          format: int64
          readOnly: true
        name:
          type: string

links部分包含命名链接定义,在本例中 - 只有一个名为GetUserByUserId 的链接。链接名称只能包含以下字符:

A..Z a..z 0..9 . _ -

每个链接包含以下信息:

  • operationIdoperationRef指定目标操作。它可以是当前或外部 API 规范中的相同操作或不同操作。operationId仅用于本地链接,operationRef可以链接到本地和外部操作。
  • parameters和/或requestBody指定要传递给目标操作的值的部分。运行时表达式语法用于从父操作中提取这些值。
  • (可选)server目标操作应使用的 ,如果它与默认服务器不同。
  • (可选)description此链接的A。CommonMark语法可用于富文本表示。

本页的其余部分将详细介绍这些关键字。

操作编号

如果已operationId指定目标操作,则链接可以指向此 ID - 如上图所示。这种方法只能用于本地链接,因为这些operationId值是在当前 API 规范的范围内解析的。

操作参考

operationRef不可用时可以使用operationIdoperationRef是使用 JSON Reference 语法对目标操作的引用 - 与$ref关键字使用的相同。引用可以是本地的(在当前 API 规范内):

operationRef: '#/paths/~1users~1{userId}/get'

或外部:

operationRef: 'https://anotherapi.com/openapi.yaml#/paths/~1users~1{userId}/get'
operationRef: './operations/getUser.yaml'

在这里,字符串#/paths/~1users~1{userId}/get实际上意味着#/paths//users/{userId}/get,但路径名中的内斜线 / 需要转义,~1因为它们是特殊字符。

#/paths/~1users~1{userId}/get
   │       │               │
   │       │               │
paths:     │               │
  /users/{userId}:         │
    get:  ─────────────────┘
      ...

此语法可能难以阅读,因此我们建议仅将其用于外部链接。在本地链接的情况下,更容易分配operationId给所有操作并链接到这些 ID。

参数和请求体

链接最重要的部分是根据原始操作的值计算目标操作的输入。这就是关键字parametersrequestBody关键字的用途。

links:
            # GET /users/{userId}
            GetUserByUserId:
              operationId: getUser
              parameters:
                userId: '$response.body#/id'
            # POST /users/{userId}/manager with the manager ID in the request body
            SetManagerId:
              operationId: setUserManager
              requestBody: '$response.body#/id'

语法是*parameter_name: value*or requestBody: value。参数名称和请求正文是目标操作的参数名称和请求体。无需列出所有参数,只需列出链接所需的参数即可。同样,requestBody仅当目标操作具有正文并且链接目的是定义正文内容时才使用。如果两个或多个参数具有相同的名称,请在名称前加上参数位置 - *pathquery、*headercookie,如下所示:

parameters:
  path.id:  ...
  query.id: ...

参数 和 的值requestBody 可以通过以下方式定义:

  • 运行时表达式,例如 $response.body#/id,引用原始操作的请求或响应中的值,
  • 包含嵌入式运行时表达式的字符串,例如 ID_{$response.body#/id}
  • 硬编码值——字符串、数字、数组等,例如mystringor true

如果您需要为目标操作传递评估参数和硬编码参数的特定组合,您通常会使用常量值。

paths:
  /date_ranges:
    get:
      summary: Get relative date ranges for the report.
      responses:
        '200':
          description: OK
          content:
            application/json:
              example: [Today, Yesterday, LastWeek, ThisMonth]
          links:
            ReportRelDate:
              operationId: getReport
              # Call "getReport" with the `rdate` parameter and with empty `start_date` and `end_date`
              parameters:
                rdate: '$response.body#/1'
                start_date: ''
                end_date: ''
  # GET /report?rdate=...
  # GET /report?start_date=...&end_date=...
  /report:
    get:
      operationId: getReport
      ...

运行时表达式语法

OpenAPI 运行时表达式是用于从操作的请求和响应中提取各种值的语法。链接使用运行时表达式来指定要传递给链接操作的参数值。这些表达式被称为“运行时”,因为这些值是从 API 调用的实际请求和响应中提取的,而不是API 规范中提供的示例值。下表描述了运行时表达式语法。所有的表述是指在当前操作,其中links被定义。

表达 描述
$url 完整的请求 URL,包括查询字符串。
$method 请求 HTTP 方法,例如 GET 或 POST。
$request.query.*param_name* 指定查询参数的值。该参数必须在操作的parameters部分中定义,否则无法对其进行评估。参数名称区分大小写。
$request.path.*param_name* 指定路径参数的值。该参数必须在操作的parameters部分中定义,否则无法对其进行评估。参数名称区分大小写。
$request.header.*header_name* 指定请求头的值。此标头必须在操作的parameters部分中定义,否则无法对其进行评估。标题名称不区分大小写。
$request.body 整个请求正文。
$request.body*#/foo/bar* 由 JSON 指针指定的请求正文的一部分。
$statusCode 响应的 HTTP 状态代码。例如,200 或 404。
$response.header.*header_name* 指定响应头的完整值,作为字符串。标题名称不区分大小写。不需要在响应的headers部分中定义标头。
$response.body 整个响应体。
$response.body*#/foo/bar* 由 JSON 指针指定的请求正文的一部分。
foo{$request.path.id}bar 将表达式{}括在花括号中以将其嵌入到字符串中。

笔记:

  • 除非另有说明,否则计算出的表达式与引用的值具有相同的类型。
  • 如果无法计算运行时表达式,则不会将参数值传递给目标操作。

例子

考虑以下请求和响应:

GET /users?limit=2&total=true
Host: api.example.com
Accept: application/json

HTTP/1.1 200 OK
Content-Type: application/json
X-Total-Count: 37
{
  "prev_offset": 0,
  "next_offset": 2,
  "users": [
    {"id": 1, "name": "Alice"},
    {"id": 2, "name": "Bob"}
  ]
}

下面是运行时表达式的一些示例以及它们计算的值:

表达 结果 评论
$url http://api.example.com/users?limit=2&total=true
$method 得到
$request.query.total 真的 total 必须定义为查询参数。
$statusCode 200
$response.header.x-total-count 37 假设X-Total-Count定义为响应头。标题名称不区分大小写。
$response.body#/next_offset 2
$response.body#/users/0 {"id": 1, "name": "Alice"} JSON 指针(#/…部分)使用基于 0 的索引来访问数组元素。但是没有通配符语法,因此无效。$response.body#/users/*****/id
$response.body#/users/1 {"id": 2, "name": "Bob"}
$response.body#/users/1/name 鲍勃
ID_{$response.body#/users/1/id} ID_2

服务器

默认情况下,目标操作是针对其默认服务器调用的- globalservers或 operation-specific servers。但是,服务器可以被使用server关键字的链接覆盖。server与全局服务器具有相同的字段,但它是单个服务器而不是数组。

servers:
  - url: https://api.example.com
...
          links:
            GetUserByUserId:
              operationId: getUser
              parameters:
                userId: '$response.body#/id'
              server:
                url: https://new-api.example.com/v2

重用链接

链接可以内联定义(如在前面的示例中),或放置在全局components/links部分中并links通过$ref. 如果多个操作以相同的方式链接到另一个操作,这会很有用 - 引用有助于减少代码重复。在以下示例中,“创建用户”和“更新用户”操作都在响应正文中返回用户 ID,该 ID 用于“获取用户”操作。源操作重用来自 的相同链接定义components/links

paths:
  /users:
    post:
      summary: Create a user
      operationId: createUser
      ...
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: integer
                    format: int64
                    description: ID of the created user.
          links:
            GetUserByUserId:
              $ref: '#/components/links/GetUserByUserId'    # <-------
  /user/{userId}:
    patch:
      summary: Update user
      operationId: updateUser
      ...
      responses:
        '200':
          description: The updated user object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
          links:
            GetUserByUserId:
              $ref: '#/components/links/GetUserByUserId'    # <-------

    get:
      summary: Get a user by ID
      operationId: getUser
      ...
components:
  links:
    GetUserByUserId:   # <----- The $ref's above point here
      description: >
        The `id` value returned in the response can be used as
        the `userId` parameter in `GET /users/{userId}`.
      operationId: getUser
      parameters:
        userId: '$response.body#/id'

参考

链接对象

回调

在 OpenAPI 3 规范中,您可以定义回调– 异步、带外请求,您的服务将发送到其他服务以响应某些事件。这有助于您改进 API 提供给客户的工作流程。回调的一个典型例子是订阅功能——用户订阅你服务的某些事件,并在这个或那个事件发生时收到通知。例如,电子商店可以在每次购买时向经理发送通知。这些通知将是“带外”的,也就是说,它们将通过访问者工作的连接之外的连接,并且它们将是异步的,因为它们将超出常规的请求-响应流。在 OpenAPI 3 中,您可以定义“订阅”操作的格式以及回调消息的格式和对这些消息的预期响应。

回调示例

让我们创建一个回调定义——一个简单的 webhook 通知。假设您的 API 提供了一个POST /subscribe需要在请求正文中包含回调 URL的操作:

POST /subscribe
Host: my.example.com
Content-Type: application/json
{
  "callbackUrl": "https://myserver.com/send/callback/here"
}

API 确认订阅——

HTTP/1.1 201 Created

— 稍后发送有关某些事件的通知:

POST /send/callback/here
Host: myserver.com
Content-Type: application/json
{
  "message": "Something happened"
}

现在让我们定义/subscribe操作:

openapi: 3.0.0
info:
  version: 0.0.0
  title: test
paths:
  /subscribe:
    post:
      summary: Subscribe to a webhook
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                callbackUrl:   # Callback URL
                  type: string
                  format: uri
                  example: https://myserver.com/send/callback/here
              required:
                - callbackUrl
      responses:
        '201':
          description: Webhook created

现在让我们在这个操作中添加 callbacks 关键字来定义一个回调:

paths:
  /subscribe:
    post:
      summary: Subscribe to a webhook
      requestBody:callbacks:   # Callback definition
        myEvent:   # Event name
          '{$request.body#/callbackUrl}':   # The callback URL,
                                            # Refers to the passed URL
            post:
              requestBody:   # Contents of the callback message
                required: true
                content:
                  application/json:
                    schema:
                      type: object
                      properties:
                        message:
                          type: string
                          example: Some event happened
                      required:
                        - message
              responses:   # Expected responses to the callback message
                '200':
                  description: Your server returns this code if it accepts the callback

使用运行时表达式来引用请求字段

如您所见,我们{$request.body#/callbackUrl}在示例中使用了表达式。它是一个运行时表达式,用于设置POST /subscribe将在回调中使用请求的哪些数据。运行时意味着与 API 端点不同,此 URL 事先未知,并在运行时根据 API 客户端提供的数据进行评估。此值因客户端而异。例如,POST /subscribe请求可以如下所示:

POST /subscribe?p1=query-param-value HTTP/1.1
Host: my.example.com
Content-Type: application/json
Content-Length: 187
{
  "callbackUrl" : "http://my.client.com/callback"
}
201 Created
Location: http://my.example.com?id=123

您可以使用以下表达式来引用其数据:

表达 例子 描述
{$url} /subscribe 父操作 URL。
{$method} POST 回调请求的方法。
{$request.path.eventType} myEvent 事件名称。
{$request.query.*param-name*} query-param-valuep1查询参数) 指定查询参数的值。
{$request.header.*header-name*} application/json (内容类型标头) “订阅”请求的指定标头。
{$request.body#/*field-name*} callbackUrl 请求正文中的一个字段。 如果该字段是一个数组,请使用类似的语法。{$request.body#/*arrayField*/*2*}
{$response.header.*header-name*} http://my.example.com?id=123 (位置标题) 指定响应头的值 (对“订阅”请求的响应)。

您可以在回调定义中将运行时表达式与静态数据结合使用。例如,您可以通过以下方式定义回调 URL:

{$request.body#callbackUrl}/data:
– or –
{$request.body#/callbackUrl}/{$request.query.eventType}:

您可以使用表达式来指定查询参数:

{$request.body#/callbackUrl}/data?p1={$request.query.eventType}

如果字符串同时包含运行时表达式和静态文本,则应将运行时表达式括在花括号中。如果整个字符串是运行时表达式,则可以跳过大括号。

多次回调

正如我们上面所说,您可以使用一个“订阅”操作来定义多个回调:

/subscribe:
    post: 
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                inProgressUrl:
                  type: string
                failedUrl:  
                  type: string
                successUrl:
                  type: string
      responses:
        '200': 
          description: OK
      callbacks:
        inProgress:
          '{$request.body#/inProgressUrl}':
            post:
              requestBody: 
                $ref: '#/components/requestBodies/callbackMessage1'
              responses:
                '200':
                  description: OK
          '{$request.body#/failedUrl}':
            post:
              requestBody: 
                $ref: '#/components/requestBodies/callbackMessage2'
              responses:
                '200':
                  description: OK
          '{$request.body#/successUrl}':
            post:
              requestBody:
                $ref: '#/components/requestBodies/callbackMessage3'
              responses:
                '200':
                  description: OK

取消订阅回调

您实现取消订阅机制的方式取决于您。例如,接收服务器可以响应回调消息返回特定代码,以表明它不再对回调感兴趣。在这种情况下,客户端只能在响应回调请求时取消订阅。为了允许客户端随时取消订阅,您的 API 可以提供特殊的“取消订阅”操作。这是一种比较常见的做法。在这种情况下,您的服务可以为每个订阅者生成一个 ID 或令牌,并在响应“订阅”请求时返回此 ID 或令牌。要取消订阅,客户端可以将此 ID 传递给“取消订阅”操作以指定要删除的订阅者。以下示例演示了如何在规范中定义此行为:

paths:
  /subscribe:
    description: Add a subscriber
    post:
      parameters:
        - name: callbackUrl
          in: query
          required: true
          schema:
            type: string
            format: uri
        - name: event
          in: query
          required: true
          schema:
            type: string
      responses:
        '201':
          description: Added
          content:
            application/json:
              type: object
              properties:
                subscriberId: 
                  type: string
                  example: AAA-123-BBB-456                    
      links:  # Link the returned id with the unsubscribe operation
        unsubscribeOp:
          operationId: unsubscribeOperation
              parameters: 
                Id: $response.body#/subscriberId
      callbacks:
        myEvent:
          '{$request.query.callbackUrl}?event={$request.query.event}':
            post:
              requestBody:
                content:
                  application/json:
                    example:
                      message: Some event
              responses:
                '200':
                  description: OK

  /unsubscribe:
    post:
      operationId: unsubscribeOperation
      parameters:
        - name: Id
          in: query
          required: true
          schema:
            type: string

组件部分

通常,多个 API 操作具有一些公共参数或返回相同的响应结构。为避免代码重复,您可以将公共定义放在全局 components部分并使用$ref. 在下面的示例中,用户对象的重复定义被替换为单个组件和对该组件的引用。前:

paths:
  /users/{userId}:
    get:
      summary: Get a user by ID
      parameters:
        ...
      responses:
        '200':
          description: A single user.
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: integer
                  name:
                    type: string
  /users:
    get:
      summary: Get all users
      responses:
        '200':
          description: A list of users.
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: integer
                    name:
                      type: string

后:

paths:
  /users/{userId}:
    get:
      summary: Get a user by ID
      parameters:
        ...
      responses:
        '200':
          description: A single user.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
  /users:
    get:
      summary: Get all users
      responses:
        '200':
          description: A list of users.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/User'
components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string

组件结构

components作为各种可重用定义的容器——模式(数据模型)、参数、响应、示例等。中的定义components对 API 没有直接影响,除非您从components. 也就是说,components不是适用于所有操作的参数和响应;它们只是可以在其他地方引用的信息。在 下components,定义按类型分组 – schemasparameters依此类推。以下示例列出了可用的小节。所有小节都是可选的。

components:
  # Reusable schemas (data models)
  schemas:
    ...
  # Reusable path, query, header and cookie parameters
  parameters:
    ...
  # Security scheme definitions (see Authentication)
  securitySchemes:
    ...
  # Reusable request bodies
  requestBodies:
    ...
  # Reusable responses, such as 401 Unauthorized or 400 Bad Request
  responses:
    ...
  # Reusable response headers
  headers:
    ...
  # Reusable examples
  examples:
    ...
  # Reusable links
  links:
    ...
  # Reusable callbacks
  callbacks:
    ...

每个小节包含一个或多个命名组件(定义):

components:
  schemas:
    User:
      type: object
      ...
    Pet:
      type: object
      ...

组件名称只能包含以下字符:

A..Z a..z 0..9 . _ -

有效名称的示例:

User
New_User
org.example.User
401-Unauthorized

组件名称用于通过$refAPI 规范的其他部分引用组件:

$ref: '#/components/<type>/<name>'

例如:

$ref: '#/components/schemas/User'

一个例外是securitySchemes通过名称直接引用的定义 (请参阅身份验证)。

组件示例

下面是一个components包含可重用数据模式、参数和响应的示例。其他组件类型(链接、示例等)的定义类似。

components:
  #-------------------------------
  # Reusable schemas (data models)
  #-------------------------------
  schemas:
    User:             # Can be referenced as '#/components/schemas/User'
      type: object
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
    Error:            # Can be referenced as '#/components/schemas/Error'
      type: object
      properties:
        code:
          type: integer
        message:
          type: string
  #-------------------------------
  # Reusable operation parameters
  #-------------------------------
  parameters:
    offsetParam:      # Can be referenced via '#/components/parameters/offsetParam'
      name: offset
      in: query
      description: Number of items to skip before returning the results.
      required: false
      schema:
        type: integer
        format: int32
        minimum: 0
        default: 0
    limitParam:       # Can be referenced as '#/components/parameters/limitParam'
      name: limit
      in: query
      description: Maximum number of items to return.
      required: false
      schema:
        type: integer
        format: int32
        minimum: 1
        maximum: 100
        default: 20
  #-------------------------------
  # Reusable responses
  #-------------------------------
  responses:
    404NotFound:       # Can be referenced as '#/components/responses/404NotFound'
      description: The specified resource was not found.
    ImageResponse:     # Can be referenced as '#/components/responses/ImageResponse'
      description: An image.
      content:
        image/*:
          schema:
            type: string
            format: binary
    GenericError:      # Can be referenced as '#/components/responses/GenericError'
      description: An error occurred.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'

外部定义的组件

在个别定义components可内联指定(如在前面的例子中)或使用一个$ref外部定义参考:

components:
  schemas:
    Pet:
      $ref: '../models/pet.yaml'
      # Can now use use '#/components/schemas/Pet' instead
    User:
      $ref: 'https://api.example.com/v2/openapi.yaml#/components/schemas/User'
      # Can now use '#/components/schemas/User' instead
  responses:
    GenericError:
      $ref: '../template-api.yaml#/components/responses/GenericError'
      # Can now use '#/components/responses/GenericError' instead

通过这种方式,您可以为可以使用的外部定义定义本地“别名”,而不是在所有引用中重复外部文件路径。如果引用文件的位置发生变化,您只需在一个地方(在components)而不是在所有引用中更改它。

与 OpenAPI 2.0 的差异

OpenAPI的2.0对可重用组件单独的章节- ,,和。在 OpenAPI 3.0 中,它们都被移到了. 此外,被重命名为和 被重命名为(注意不同的拼写:vs )。引用会相应地更改以反映新结构:definitions``parameters``responses``securityDefinitions``components``definitions``schemas``securityDefinitions``securitySchemes``schem*A*s``securitySchem*E*s

OpenAPI 2.0                    OpenAPI 3.0
'#/definitions/User'         → '#/components/schemas/User'
'#/parameters/offsetParam'   → '#/components/parameters/offsetParam'
'#/responses/ErrorResponse'  → '#/components/responses/ErrorResponse'

使用 $ref

当您记录 API 时,通常会有一些您在多个 API 资源中使用的功能。在这种情况下,您可以为此类元素创建一个片段,以便在需要时多次使用它们。使用 OpenAPI 3.0,您可以引用托管在任何位置的定义。它可以是同一台服务器,也可以是另一台服务器,例如 GitHub、SwaggerHub 等。要引用定义,请使用$ref关键字:

$ref: 'reference to definition'

例如,假设您有以下架构对象,您想在响应中使用它:

JSON 示例 YAML 示例
"components": { "schemas": { "user": { "properties": { "id": { "type": "integer" }, "name": { "type": "string" } } } }} components: schemas: User: properties: id: type: integer name: type: string

要引用该对象,您需要$ref在响应中添加相应的路径:

JSON 示例 YAML 示例
"responses": { "200": { "description": "The response", "schema": { "$ref": "#/components/schemas/user" } }} responses: '200': description: The response schema: $ref: '#/components/schemas/User'

的值$ref使用JSON Reference表示法,以 开头的部分#使用JSON Pointer表示法。此表示法允许您指定要引用的目标文件或文件的特定部分。在前面的例子中,#/components/schemas/User意味着解析从当前文档的根开始,然后一个接一个地找到componentsschemas、的值User

$ref 语法

根据RFC3986$ref字符串值 ( JSON Reference ) 应该包含一个 URI,它标识您引用的 JSON 值的位置。如果字符串值不符合 URI 语法规则,则在解析过程中会导致错误。$refJSON Reference 对象之外的任何成员都将被忽略。检查此列表以获取特定情况下 JSON 引用的示例值:

  • 本地参考-$ref: '#/definitions/myElement' #手段去到当前文档的根目录,然后找到元素definitionsmyElement一个一个之后。

  • 远程参考

    $ref: 'document.json'

    使用位于同一服务器和同一位置的整个文档。

    • 位于同一文件夹中的文档元素-$ref: 'document.json#/myElement'
    • 位于父文件夹中的文档元素-$ref: '../document.json#/myElement'
    • 位于另一个文件夹中的文档元素-$ref: '../another-folder/document.json#/myElement'
  • URL 引用

    $ref: 'http://path/to/your/resource'

    使用位于不同服务器上的整个文档。

    • 存储在不同服务器上的文档的特定元素-$ref: 'http://path/to/your/resource.json#/myElement'
    • 使用相同协议(例如 HTTP 或 HTTPS)的不同服务器上的文档$ref: '//anotherserver.com/files/example.json'

注意#/components/schemas/User在 YAML等使用本地引用时,请将值括在引号中:'#/components/schemas/User'. 否则将被视为注释。

转义字符

/~是 JSON 指针中的特殊字符,按字面使用时需要转义(例如,在路径名中)。

特点 逃脱
~ ~0
/ ~1

例如,要引用 path /blogs/{blog_id}/new~posts,您可以使用:

$ref: '#/paths/~1blogs~1{blog_id}~1new~0posts'

注意事项

可以使用 $ref 的地方

一个常见的误解是$ref允许在 OpenAPI 规范文件中的任何位置。实际上$ref只允许在OpenAPI 3.0 规范明确指出该值可能是引用的地方。例如,$ref不能在info节和直接下使用paths

openapi: 3.0.0
# Incorrect!
info:
  $ref: info.yaml
paths:
  $ref: paths.yaml

但是,您可以使用$ref单独的路径,如下所示:

paths:
  /users:
    $ref: '../resources/users.yaml'
  /users/{userId}:
    $ref: '../resources/users-by-id.yaml'

$ref 和兄弟元素

a 的任何同级元素都将$ref被忽略。这是因为它的$ref工作原理是用它所指向的定义替换自身及其级别上的所有内容。考虑这个例子:

components:
  schemas:
    Date:
      type: string
      format: date
    DateWithExample:
      $ref: '#/components/schemas/Date'
      description: Date schema extended with a `default` value... Or not?
      default: 2000-01-01

在第二个模式中,descriptiondefault属性被忽略,因此该模式最终与引用的Date模式完全相同。

API 一般信息

在规范中包含有关 API 的一般信息被认为是一种很好的做法:版本号、许可说明、联系数据、文档链接等。我们特别建议对公开可用的 API 执行此操作;因为这会增加用户对贵公司提供的服务的信心。要指定 API 元数据,请使用顶级info对象的属性:

openapi: 3.0.0
info:
  # You application title. Required.
  title: Sample Pet Store App
  # API version. You can use semantic versioning like 1.0.0, 
  # or an arbitrary string like 0.99-beta. Required.
  version: 1.0.0 
  # API description. Arbitrary text in CommonMark or HTML.
  description: This is a sample server for a pet store.
  # Link to the page that describes the terms of service.
  # Must be in the URL format.
  termsOfService: http://example.com/terms/
  # Contact information: name, email, URL.
  contact:
    name: API Support
    email: support@example.com
    url: http://example.com/support
  # Name of the license and a URL to the license description.
  license:
    name: Apache 2.0
    url: http://www.apache.org/licenses/LICENSE-2.0.html
  # Link to the external documentation (if any).
  # Code or documentation generation tools can use description as the text of the link. 
  externalDocs:
    description: Find out more
    url: http://example.com

titleversion属性是必需的,其他都是可选的。

使用标签对操作进行分组

您可以tags为每个 API 操作分配一个列表。标记操作可能由工具和库以不同方式处理。例如,Swagger UI 用于tags对显示的操作进行分组。

paths:
  /pet/findByStatus:
    get:
      summary: Finds pets by Status
      tags:
        - pets
      ...
  /pet:
    post:
      summary: Adds a new pet to the store
      tags:
        - pets
      ...
  /store/inventory:
    get:
      summary: Returns pet inventories
      tags:
        - store
      ...

或者,您可以使用根级别的全局部分为每个标签指定description和。此处的标签名称应与操作中使用的标签名称相匹配。externalDocs``tags

tags:
  - name: pets
    description: Everything about your Pets
    externalDocs:
      url: http://docs.my-api.com/pet-operations.htm
  - name: store
    description: Access to Petstore orders
    externalDocs:
      url: http://docs.my-api.com/store-orders.htm

全局标签部分中的标签顺序还控制 Swagger UI 中的默认排序。请注意,即使未在根级别定义,也可以在操作中使用标签。

OpenAPI 扩展

扩展(也称为规范扩展供应商扩展)是以 开头的自定义属性x-,例如x-logo. 它们可用于描述标准 OpenAPI 规范未涵盖的额外功能。许多支持 OpenAPI 的 API 相关产品使用扩展来记录它们自己的属性,例如 Amazon API Gateway、ReDoc、APIMatic 等。API 规范的根级别和以下位置支持扩展:

  • info 部分
  • paths 部分、单独的路径和操作
  • 运行参数
  • responses
  • tags
  • 安全方案

扩展值可以是原始值、数组、对象或null. 如果值是一个对象或对象数组,则该对象的属性名称不需要以 开头x-

例子

使用 Amazon API Gateway 自定义授权方的 API 可能包含类似于以下内容的扩展:

components:
  securitySchemes:
    APIGatewayAuthorizer:
      type: apiKey
      name: Authorization
      in: header
      x-amazon-apigateway-authtype: oauth2
      x-amazon-apigateway-authorizer:
        type: token
        authorizerUri: arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:account-id:function:function-name/invocations
        authorizerCredentials: arn:aws:iam::account-id:role
        identityValidationExpression: "^x-[a-z]+"
        authorizerResultTtlInSeconds: 60

2.0


文章作者: 杰克成
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 杰克成 !
评论
  目录