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
45 stars 17 forks source link

Incorrect OpenAPI additionalProperties for a list object #191

Closed ysavourel closed 1 year ago

ysavourel commented 1 year ago

It seems the openApi processor doesn't generate the correct JSON for maps that have a list has value. (Using Javalin 5.5.0 with the OpenAPI plugin 5.5.0-1) I have the following class:

public class MyData {
    private String stuff = "test-1";
    private Map<String, List<Entry>> mapOfEntries;

    @OpenApiDescription(value = "Some stuff.")
    public String getStuff() {
        return stuff;
    }
    public void setStuff(String stuff) {
        this.stuff = stuff;
    }
    @OpenApiDescription(value = "The map of entries.")
    public Map<String, List<Entry>> getMapOfEntries() {
        return mapOfEntries;
    }
    public void setMapOfEntries(Map<String, List<Entry>> mapOfEntries) {
        this.mapOfEntries = mapOfEntries;
    }
}

And I get the following OpenAPI output:

 "MyData" : {
        "type" : "object",
        "additionalProperties" : false,
        "properties" : {
          "stuff" : {
            "type" : "string",
            "description" : "Some stuff."
          },
          "mapOfEntries" : {
            "type" : "object",
            "additionalProperties" : {
              "$ref" : "#/components/schemas/Entry"
            },
            "description" : "The map of entries."
          }
        }
      }

As you can see the mapOfEntries property is defined as just a single Entry object instead of a list. I believe the additionalProperties should be more like this:

...
"mapOfEntries": {
  "type": "object",
  "additionalProperties": {
    "type": "array",
    "items": {
      "$ref": "#/components/schemas/Entry"
    }
  },
  "description": "The map of entries."
}
...

I'm missing some additional annotation(s)?

Even if the list is a list of simple strings (Map<String, List<String>>) we get the property defined as just one string:

...
          "mapOfEntries" : {
            "type" : "object",
            "additionalProperties" : {
              "type" : "string"
            },
            "description" : "The map of entries."
          }
...
dzikoysk commented 1 year ago

The problem with OpenApi is that it's written for JS-like structures, and it's kinda weird the deeper we go. I believe that additionalProperties & array type are not directly documented in the spec:

It looks like this is even an issue on Swagger side:

Anyway, I see the problem. We could adjust that part as it seems to be supported by some codegen libs: