swagger-core icon indicating copy to clipboard operation
swagger-core copied to clipboard

Strings "yes" and "no" serialized as boolean

Open jimirocks opened this issue 5 years ago • 4 comments

The strings "yes" and "no" are serialized wrongly to YAML, when for instance used in enums. Seems the underlying jackson library works well until configured to serve OpenAPI purposes.

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import io.swagger.v3.core.util.Yaml

fun main(args: Array<String>) {
    val yamlWriter = Yaml.pretty()
    println(yamlWriter.writeValueAsString("no"))

    println(ObjectMapper(YAMLFactory()).writeValueAsString("no"))
}

Produces following output:

no

--- "no"

The first one is unfortunately YAML's boolean...

jimirocks avatar Dec 03 '19 14:12 jimirocks

That's inaccurate. In YAML 1.1 has an extension that allows interpreting on, off, yes, no (with capitalization variations) as boolean values, but it's not part of the core spec. In YAML 1.2 it doesn't exist at all. While for clarity we should quote those values, it can also be overcome by using the right YAML parser (with proper configuration).

webron avatar Dec 03 '19 16:12 webron

Well, you are right. But I would assume that swagger library would parse what it serializes into the same semantic. But that's apparently not possible. Try this snippet

import io.swagger.v3.core.util.Yaml
import io.swagger.v3.oas.models.Components
import io.swagger.v3.oas.models.OpenAPI
import io.swagger.v3.oas.models.media.StringSchema
import io.swagger.v3.parser.OpenAPIV3Parser

fun main(args: Array<String>) {
    val yamlWriter = Yaml.pretty()

    val schema = StringSchema().addEnumItem("yes").addEnumItem("no")
    val openApi = OpenAPI().apply {
        components = Components().addSchemas("testIt", schema)
    }
    val stringOpenApi = yamlWriter.writeValueAsString(openApi)
    println(stringOpenApi)

    val parseResult = OpenAPIV3Parser().readContents(stringOpenApi)
    println(parseResult.openAPI.components.schemas.get("testIt")?.enum)
}

Producing

openapi: 3.0.1
components:
  schemas:
    testIt:
      type: string
      enum:
      - yes
      - no

[true, false]

This doesn't feel correct to me - I created string schema with enums values "yes" and "no" but after serialization roudntrip using the same library my "yes" and "no" turned to "true" and "false".

So please either add clarifying quotes, or make the parser compatible with the serializer (this is IMHO impossible). The option would be to use YAML 1.2 - which would be nice, but it seems the underlying jackson doesn't support it yet.

jimirocks avatar Jan 28 '20 08:01 jimirocks

The current workaround is

val yamlWriter = Yaml.pretty().apply {
        (factory as YAMLFactory).configure(YAMLGenerator.Feature.MINIMIZE_QUOTES, false)
    }

This uses all the configuration from swagger library but the shaved quoting.

jimirocks avatar Jan 28 '20 08:01 jimirocks

related https://github.com/swagger-api/swagger-parser/issues/1205

gracekarina avatar Apr 20 '22 23:04 gracekarina