Search code examples
javaswaggeropenapi

Serializing OpenAPI objects created by swagger-parser to specification file


I'm trying to create a process that takes an OpenAPI specification file created by an external system, performs some modifications to make them work better as a Spring API, then writes the resulting file, which is then consumed by openapi-generator to create the API and Model classes.

I'm using swagger-parser to read the original file and I can make changes to the resulting OpenAPI objects. I've tried a couple of ways of serializing these objects to a JSON files, but openapi-generator runs into problems parsing these files.

Generally, the code looks like this:

SwaggerParseResult result = new OpenAPIParser().readLocation( INPUT_FILE, null, null );
OpenAPI openAPI = result.getOpenAPI();

// at this point, result.getMessages() is an empty list

/* ... tweak the API description ... */

String rawData = Json.pretty(openAPI);
try {
  FileUtils.writeStringToFile( OUTPUT_FILE, rawData, Charset.defaultCharset() );
} catch (IOException e) {
  throw new RuntimeException("Error writing file", e);
}

That Json.pretty is Swagger's own Json class for serializing an OpenAPI object.

The validation errors I'm seeing include:

  • Schemas end up with both a type property (a string) and types (an array of strings).
  • Extension fields (e.g., x-whatever) on objects are being rendered as fields within an extensions object.
  • A few extra internal fields on the OpenAPI objects end up in the JSON

As an example, this looks like:

  "components" : {
    "schemas" : {
      "something" : {
        "minLength" : 1,
        "maxLength" : 10,
        "type" : "string",
        "types" : [ "string" ],
        "extensions" : {
          "x-whatever" : true
        }
      }
...

I've tried constructing my own ObjectMapper with some custom mixins to hide/modify these problems, but it's becoming very complicated.

So how is one expected to serialize an OpenAPI object to a file in such a way that it can be parsed again by Swagger's own OpenAPIParser?


Solution

  • Make sure you use Json.pretty() from the correct Swagger package:

    • OpenAPI 3.0.x → io.swagger.v3.core.util
    • OpenAPI 3.1 → Json31.pretty() from io.swagger.v3.core.util; see here about the differences in OAS 3.1 vs 3.0 (de)serialization
    • OpenAPI 2.0 → io.swagger.util