我如何从多个完全不相关的OpenAPI文件中聚合路径?

huangapple go评论79阅读模式
英文:

How can I aggregate paths from multiple completely unrelated OpenAPI files?

问题

我正在开发一个Maven插件,用于将一些我需要的文件与JAR文件一起打包。其中一个文件是名为component-descriptor.yaml的OpenAPI文件。

除了其他事项外,插件需要检查项目直接依赖的component-descriptor.yaml,并将这些文件中指定的路径“聚合”到当前项目的文件中。(我不关心其他任何细节,如信息、标签等。)这些文件彼此完全独立,不使用$ref来相互引用,如此问题中所述 - 我不能使用$ref或类似的机制,因为模块之间没有依赖。

我怎样才能实现这个目标?

我已经能够检索所有直接依赖项的component-descriptor.yaml并使用io.swagger逐个解析它们。我知道我可以将文件解析为Java对象并将路径列表连接成单个对象,但我该如何将其转换回OpenAPI文件呢?我在Swagger中找不到支持这样做的任何功能。

英文:

I am working on a Maven plugin to package some files that I need along with the JAR file. One of those files is an OpenAPI file named component-descriptor.yaml.

Among other things, the plugin needs to check the component-descriptor.yaml of the project's direct dependencies and "aggregate" the paths specified in those files into the current project's file. (I don't care about any of the other details like info, tags, etc.) These files are completely independent of each other and do not use $ref to refer to each other as described in this question - I cannot use $ref or similar mechanisms because the modules do not depend on each other.

How can I accomplish this goal?

I was able to retrieve the component-descriptor.yaml of all direct dependencies and parse them (individually) using io.swagger. I know I could parse the files into Java objects and concatenate the list of paths into a single object, but how can I then turn that back into an OpenAPI file? I couldn't find any support in Swagger for doing so.

答案1

得分: 2

以下是您要翻译的内容:

至我所查找,似乎没有“自动”完成此操作的方法。但我找到了一个相当直接的方法:

步骤1:检索OpenAPI文件并将其解析为OpenAPI对象。

您可以使用Swagger的OpenAPIV3Parser来实现:

对于每个您拥有的fileLocation(OpenAPI YAML文件),可以使用以下代码进行循环:

OpenAPI parseOpenAPI(FileLocation fileLocation) throws MojoFailureException {
    SwaggerParseResult swaggerParseResult = parser.readLocation(fileLocation.getUri().toString(), null, null);

    if (null == swaggerParseResult || null == swaggerParseResult.getOpenAPI()) {
        throw new MojoFailureException("Failed to parse the openAPI: " + fileLocation);
    }

    return swaggerParseResult.getOpenAPI();
}

步骤2:合并对象

这一步与您期望的基本相同,只需将其他OpenAPI对象中所需的任何内容添加到我的主要OpenAPI对象中。

private OpenAPI aggregateOpenAPI(FileLocation mainopenAPI, List<FileLocation> openAPILocations) throws IOException, MojoFailureException {

    OpenAPI projectOpenAPI = getOpenAPIFile(mainopenAPI);

    if (projectOpenAPI.getComponents() == null) {
        projectOpenAPI.setComponents(new Components());
    }

    for (FileLocation fileLocation: openAPILocations) {

        OpenAPI openAPI = getOpenAPIFile(fileLocation);
        openAPI.getPaths().forEach(projectOpenAPI.getPaths()::addPathItem);
        Components components = openAPI.getComponents();
        if (components != null) {
            if (components.getParameters() != null) {
                components.getParameters().forEach(projectOpenAPI.getComponents()::addParameters);
            }
            if (components.getSchemas() != null) {
                components.getSchemas().forEach(projectOpenAPI.getComponents()::addSchemas);
            }
        }
    }
    return projectOpenAPI;
}

步骤3:解析并写入文件

当我撰写此问题时,我忽略了Swagger实际上提供了将OpenAPI对象直接解析为YAML或JSON文件的能力。

String yamlOpenAPI = Yaml.pretty(projectOpenAPI);
// 或者
String jsonOpenAPI = Json.pretty(projectOpenAPI);

// 将其写入文件(确保目录和文件存在)
Files.write(Paths.get("path/to/file.yaml"), yamlOpenAPI.getBytes());

编辑:

请注意,您可能需要使用writeString而不是write来支持UTF-8字符,如下所示:

Files.writeString(Paths.get("path/to/file.yaml"), yamlOpenAPI);
英文:

As far as I could find, there isn't any "automatic" way to do this. But I have found a rather straightforward method:

Step 1: Retrieve the OpenAPI files and parse them into OpenAPI objects.

You can achieve this using Swagger OpenAPIV3Parser:

Loop the below code for each fileLocation (OpenAPI YAML file) that you have.

OpenAPI parseOpenAPI(FileLocation fileLocation) throws MojoFailureException {
    SwaggerParseResult swaggerParseResult = parser.readLocation(fileLocation.getUri().toString(), null, null);

    if (null == swaggerParseResult || null == swaggerParseResult.getOpenAPI()) {
        throw new MojoFailureException(&quot;Failed to parse the openAPI: &quot; + fileLocation);
    }

    return swaggerParseResult.getOpenAPI();
}

Step 2: Merge the objects

This step is pretty much as you'd expect, just adding anything I need from the other OpenAPI objects into my main OpenAPI object.

private OpenAPI aggregateOpenAPI(FileLocation mainopenAPI, List&lt;FileLocation&gt; openAPILocations) throws IOException, MojoFailureException {

    OpenAPI projectOpenAPI = getOpenAPIFile(mainopenAPI);

    if (projectOpenAPI.getComponents() == null) {
        projectOpenAPI.setComponents(new Components());
    }

    for (FileLocation fileLocation: openAPILocations) {

        OpenAPI openAPI = getOpenAPIFile(fileLocation);
        openAPI.getPaths().forEach(projectOpenAPI.getPaths()::addPathItem);
        Components components = openAPI.getComponents();
        if (components != null) {
            if (components.getParameters() != null) {
                components.getParameters().forEach(projectOpenAPI.getComponents()::addParameters);
            }
            if (components.getSchemas() != null) {
                components.getSchemas().forEach(projectOpenAPI.getComponents()::addSchemas);
            }
        }
    }
    return projectOpenAPI;
}

Step 3: Parse and write to a file

When I wrote this question, I was missing that Swagger actually provides the ability to parse an OpenAPI object directly into a YAML or JSON file.

String yamlOpenAPI = Yaml.pretty(projectOpenAPI);
// or
String jsonOpenAPI = Json.pretty(projectOpenAPI);

// Write it into a file (make sure directory and file exist)
Files.write(Paths.get(&quot;path/to/file.yaml&quot;), yamlOpenAPI.getBytes());

Edit:

Note that you may need to use writeString instead of write to support UTF-8 characters like so:

Files.writeString(Paths.get(&quot;path/to/file.yaml&quot;), yamlOpenAPI);

huangapple
  • 本文由 发表于 2023年5月29日 21:14:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76357706.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定