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.
As far as I could find, there isn't any "automatic" way to do this. But I have found a rather straightforward method:
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("Failed to parse the openAPI: " + fileLocation);
}
return swaggerParseResult.getOpenAPI();
}
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<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;
}
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("path/to/file.yaml"), 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("path/to/file.yaml"), yamlOpenAPI);