swagger-api / swagger-core

Examples and server integrations for generating the Swagger API Specification, which enables easy access to your REST API
http://swagger.io
Apache License 2.0
7.37k stars 2.17k forks source link

Schema description of one field overrides descriptions of other fields of same class #3900

Open pchmieli opened 3 years ago

pchmieli commented 3 years ago

Let's take an example of two simple classes:

public class GeoPointDto {

    @Schema(description = "Longitude of geo point ( -180, 180 >")
    private double lon;

    @Schema(description = "Latitude of geo point < -90, 90 >")
    private double lat;
}
public class RouteDto {

    @Schema(description = "Point where the route begins")
    private GeoPointDto startPoint;

    @Schema(description = "Intermediate point of the route")
    private GeoPointDto intermediatePoint;

    @Schema(description = "Point where the route ends")
    private GeoPointDto endPoint;
}

Expected behavior is to have three fields inside RouteDto with different descirption each. Actual behavior is that all fields has same description = "Point where the route ends" which is the description of third field.

UI: image

JSON:

  "components" : {
    "schemas" : {
      "RouteDto" : {
        "type" : "object",
        "properties" : {
          "startPoint" : {
            "$ref" : "#/components/schemas/GeoPointDto"
          },
          "intermediatePoint" : {
            "$ref" : "#/components/schemas/GeoPointDto"
          },
          "endPoint" : {
            "$ref" : "#/components/schemas/GeoPointDto"
          }
        }
      },
      "GeoPointDto" : {
        "type" : "object",
        "properties" : {
          "lon" : {
            "type" : "number",
            "description" : "Longitude of geo point ( -180, 180 >",
            "format" : "double"
          },
          "lat" : {
            "type" : "number",
            "description" : "Latitude of geo point < -90, 90 >",
            "format" : "double"
          }
        },
        "description" : "Point where the route ends"
      }
    }
  }
devoto13 commented 3 years ago

According to the specification all properties except $ref in the object should be ignored, so I guess it is unsolvable problem for the current OpenAPI Specification. Unless we inline the schema instead of using a reference, which is undesired for a lot of other reasons.

I would say that it is more consistent behavior to always ignore (maybe with a warning) any properties of the @Schema annotation on the object property when the property type is a reference to another schema. Overriding properties in the referenced schema leads to weird behavior when referenced schema is used multiple times. I understand why current behavior is used as it allows things to kinda work for nested objects used only once... Not sure how to fix this bug with the current specification.

Looks like the restriction on the $ref + other properties was lifted in the latest draft, but it will probably not get adopted by OpenAPI specification any time soon.

Cybermite commented 3 years ago

Looks like the restriction on the $ref + other properties was lifted in the latest draft, but it will probably not get adopted by OpenAPI specification any time soon.

Looks like it was adopted in 3.1.0: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#fixed-fields-19

DepickereSven commented 3 years ago

@Cybermite

It's indeed adopted in 3.1.0 Reference: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#referenceObject

rainer-wei commented 11 months ago

This issue still exists in 2.2.15 at least.

arvsr1988 commented 8 months ago

is the issue fixed in OAS 3.1 or do we need to do something different in the code?

public class RouteDto {

    @Schema(description = "Point where the route begins")
    private GeoPointDto startPoint;

    @Schema(description = "Intermediate point of the route")
    private GeoPointDto intermediatePoint;

    @Schema(description = "Point where the route ends")
    private GeoPointDto endPoint;
}
andrejb-dev commented 6 months ago

Still issue with swagger-ui 5.2.0, camel-openapi 4.3.0 and springdoc-openapi-starter 2.2.0. Not sure which is in effect. But I used this simple workaround

public class GeoPointDto {

    @Schema(description = "Longitude of geo point ( -180, 180 >")
    private double lon;

    @Schema(description = "Latitude of geo point < -90, 90 >")
    private double lat;

    public static class Start extends GeoPointDto {}
    public static class Intermediate extends GeoPointDto {}
    public static class End extends GeoPointDto {}
}

public class RouteDto {

    @Schema(description = "Point where the route begins")
    private GeoPointDto.Start startPoint;

    @Schema(description = "Intermediate point of the route")
    private GeoPointDto.Intermediate intermediatePoint;

    @Schema(description = "Point where the route ends")
    private GeoPointDto.End endPoint;
}
pedrohubner commented 1 month ago

Me and @garciagiovane found the solution at this documentation at section 13.74. How can i define different schemas for the same class?.

If we document variables that have the same type, and they have different schemas with different descriptions, at compile time the last variable description will overwrite the other ones because they have the same type.