将 OpenAPI 2.0 规范转换为 OpenAPI 3.0

1、简介

尽管 OpenAPI 3.x 规范自 2017 年起就已发布,并经历了多次更新,但目前许多 API 仍在继续使用旧版本。

本文将带你了解 OpenAPI 2.0OpenAPI 3.0 规范之间的主要区别,以及如何将 OpenAPI 2.0 规范转换为 OpenAPI 3.0

2、OpenAPI 2.0 和 OpenAPI 3.0

简单回顾一下,OpenAPI 提供了一种标准格式,用于描述人类和机器都能读懂的 HTTP API。在 3.0 版之前,OpenAPI 被称为 Swagger 规范和 Swagger 工具包的一部分。从那时起,它已成为行业标准,并经过多次更新,带来了更多改进和功能。

与 2.0 相比,OpenAPI 3.0 引入了几项根本性变化。

首先,对整体结构进行了重构,以提高可重用性。添加了一个 components(组件)块来组织现有元素(如 schemasresponsesparameters)和新元素(请求 requestBodyexamplesheaders)。一些元素被重新命名 - definitions 现在被称为 schemassecurityDefinitions 被称为 securitySchemes

此外,OpenAPI 3.0 还进一步扩展了 JSON Schema 功能。添加了 oneOfanyOfnot 等关键字,以便对复杂的数据格式进行描述和灵活验证。

3.0 版本还引入了对 cookie 参数、内容类型协商和回调机制的支持。它还扩展了安全定义并简化了现有流程。

最后,你可以在官方 更新日志 中查看完整的变更列表。

3、项目设置

创建一个示例项目。通常,我们会公开 REST 服务,并使用 OpenAPI 来定义和记录 API。不过,由于我们只是要演示如何将 2.0 版本的 OpenAPI 规范转换为更新的规范,所以还是使用公开可用的 APIpetstore.swagger.io/)吧。

虽然 YAML 规范版本也可用,但我们重点关注 JSON 格式。因此,让我们 下载 该文件并将其放在 resources 文件夹中。这样,可以轻松访问该文件,以演示转换规范的不同方式。根据不转换方法的不同,我们将通过浏览器或 curl 上传文件,将其作为参数传递,或在代码中引用。

4、工具和库

在使用 OpenAPI 规范时,有多种工具和库可供选择。让我们先来看看无需本地安装的方式,这些方式允许我们直接在浏览器中转换 API 规范版本。

4.1、Swagger Editor

Swagger Editor 除其他功能外,还允许我们上传或粘贴 API 规范,并将其转换为 OpenAPI 3.0 或其他格式。让我们提供规范,从 “编辑” 选项下的菜单中选择 “Convert to OpenAPI 3”,然后等待转换完成:

Swagger Editor

转换完成后,新版本的规范将就可以使用了。

4.2、Swagger Converter

在线版 Swagger Converter 工具提供了两种转换规范的方法。

第一种方法允许通过上传文件或粘贴 JSON 内容直接提供 OpenAPI 2.0 规范:

curl -X 'POST' \
 'https://converter.swagger.io/api/convert' \
 -H 'accept: application/json' \
 -H 'Content-Type: application/json' \
 --data-binary @swagger.json

如果 API 是公开可访问的,我们可以通过引用指向旧版本 API 规范的 URL 来转换规范:

curl -X 'GET' \
'https://converter.swagger.io/api/convert?url=https%3A%2F%2Fpetstore.swagger.io%2Fv2%2Fswagger.json' \
-H 'accept: application/json'

Swagger Converter 支持 JSON 和 YAML 格式,用户界面 友好,转换更方便。

4.3、API Spec Converter

对于公共 API,另一个选择是 api-spec-converter,这是一个支持各种 API 规范格式的开源库。让我们提供一个 URL,选择 OpenAPI 2 (Swagger) 作为源格式,OpenAPI 3.0 作为目标格式,然后点击转换:

API Spec Converter

成功完成后,转换后的规范将可供下载。

接着,让我们来了解一下有 CLI 和插件的其他工具。

4.4、Swagger Codegen

Swagger Codegen 是一个开源代码生成器。除了创建 REST 客户端、生成服务器存根(Server Stub)和各种格式的 API 文档外,我们还可以使用该库转换规范。

下载 最新版本 并执行以下命令:

java -jar swagger-codegen-cli-3.0.62.jar generate \
  -l openapi \
  -i https://petstore.swagger.io/v2/swagger.json \
  -o converted

其执行结果是 OpenAPI 3.0 规范位于指定的输出文件夹中(本例中是 converted 文件夹)。

通过选择不同的命令行选项,我们可以自定义生成过程。例如,在上面的例子中,语言(-l-lang)设置为 openapi 将生成 JSON 格式。要获得 YAML 格式的规范,需要将其设置为 openapi-yaml

4.5、OpenAPI Generator

由于 OpenAPI GeneratorSwagger Codegen 的一个 fork 版本,因此如果我们使用 OpenAPI Generator,转换过程也会类似。

使用 最新版本,运行下面的命令:

java -jar openapi-generator-cli-7.9.0.jar generate \
  -g openapi \
  -i https://petstore.swagger.io/v2/swagger.json \
  -o converted

同样,我们可以通过选择不同的生成器名称(-g)选项,如 openapi-yamlopenapi,生成 YAMLJSON 格式的规范。

需要注意的是,在 CLI 中运行 JAR 文件时,Java 版本必须兼容。否则,可能会遇到表示版本不匹配的异常:UnsupportedClassVersionError

4.6、Swagger Parser

顾名思义,Swagger 解析器 可以帮助我们解析 OpenAPI 文档。此外,我们还可以用它将旧版本的规范转换成新版本。

根据 Swagger Parser 的说明,让我们创建一个简单的方法来处理规范文件:

private static OpenAPI processSpecificationJson(final String specificationFileLocation) {
    SwaggerParseResult result = new OpenAPIParser().readLocation(specificationFileLocation, null, null);

    final OpenAPI openAPI = result.getOpenAPI();
    if (openAPI == null) {
        throw new IllegalArgumentException("Failed to parse OpenAPI specification from: " 
          + specificationFileLocation);
    }

    return openAPI;
}

接下来,可以使用 ObjectMapperwriteValueAsString() 方法将 OpenAPI 对象序列化为 JSON 格式:

private static String asJsonString(OpenAPI openAPI) throws JsonProcessingException {
    return objectMapper.writerWithDefaultPrettyPrinter()
      .writeValueAsString(openAPI);
}

通过设置相应的属性,我们提高了 JSON 输出的可读性,并排除了 null 值:

private static final ObjectMapper objectMapper;

static {
    objectMapper = new ObjectMapper();
    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
}

此时,我们就可以定义转换方法了:

public static String convert(String specificationFileLocation) throws IOException {
    if (specificationFileLocation == null || specificationFileLocation.isEmpty()) {
        throw new IllegalArgumentException("Specification file path cannot be null or empty.");
    }

    return asJsonString(processSpecificationJson(specificationFileLocation));
}

最后,进行测试。

通过确保结果不为 null 来验证转换过程:

@Test
void givenOpenApi2_whenConvert_thenSpecificationSuccessfullyConverted() throws IOException {
    String openAPI3 = SwaggerToOpenApiConverter.convert(FILE_OPEN_API_2_SPECIFICATION);

    assertNotNull(openAPI3);
}

测试通过,表明 OpenAPI 2 已正确转换。

5、总结

本文介绍了如何将 OpenAPI 2.0 规范转换为 OpenAPI 3.0,详细介绍了各种工具和库,包括 Swagger EditorConverter 等在线选项以及 Swagger CodegenOpenAPI Generator 等命令行工具。


Ref:https://www.baeldung.com/java-openapi2-openapi3-upgrade