javalin / javalin-openapi

Annotation processor for compile-time OpenAPI & JsonSchema, with out-of-the-box support for Javalin 5.x, Swagger & ReDoc
https://github.com/javalin/javalin-openapi/wiki
Apache License 2.0
44 stars 17 forks source link

BigDecimal marked as string in OpenAPI spec #167

Closed dennisameling closed 1 year ago

dennisameling commented 1 year ago

Hi! When using BigDecimal as a property type, it's being marked as "string" in the OpenAPI spec:

data class ExampleDataClass(
    @get:OpenApiName("fancy_bigdecimal")
    @get:OpenApiExample("221322.24")
    val fancyBigDecimal: BigDecimal? = null,
)
"components" : {
    "schemas" : {
      "ExampleDataClass" : {
        "type" : "object",
        "additionalProperties" : false,
        "properties" : {
          "fancy_bigdecimal" : {
            "type" : "string",
            "example" : "221322.24"
          },
        },
        "required": []
      }
  }
}

However the serializer (Jackson) turns it into a double (which we expect it to do), so the API output is inconsistent with the OpenAPI spec:

"fancy_bigdecimal": 221322.24

I tried setting OpenApiPropertyType to Double, but then the OpenAPI property spec loses its nullability 😅

    @get:OpenApiName("fancy_bigdecimal")
    @get:OpenApiExample("221322.24")
    @get:OpenApiPropertyType(Double::class)
    val fancyBigDecimal: BigDecimal? = null,
"components" : {
    "schemas" : {
      "ExampleDataClass" : {
        "type" : "object",
        "additionalProperties" : false,
        "properties" : {
          "fancy_bigdecimal" : {
            "type" : "number",
            "format": "double",
            "example" : "221322.24"
          },
        },
        "required": [ "fancy_bigdecimal" ]
      }
  }
}

One solution I could think of is adding a nullable argument to OpenApiPropertyType, so something like @get:OpenApiPropertyType(definedBy = Double::class, nullable = true). What do you think about that? Or did I simply miss an existing feature for this?

Thanks in advance again! Appreciate all your work on this library 😊

dzikoysk commented 1 year ago

I think we should keep all Big* impls as string, because JavaScript is not good in handling those types as numbers and it's just a safer default. Speaking of the custom type nullability, I'll definitely take a look at it in the evening :)

dzikoysk commented 1 year ago

So, the issue here is that it's declared as Double::class which is translated to double.class and primitives cannot be null. If you'd declare this type as java.lang.Double::class then it'd work like that, so technically it's not a bug 😛 I'll push change change with custom nullability tho since it's needed anyway :)