springdoc / springdoc-openapi

Library for OpenAPI 3 with spring-boot
https://springdoc.org
Apache License 2.0
3.25k stars 492 forks source link

Phantom properties added to objects when @JsonSerialize(as =...) implementation uses specific collection subtypes #638

Closed chadselph closed 4 years ago

chadselph commented 4 years ago

Describe the bug I have an interface being used for a response and it delegates its JSON encoding to an implementation generated by an annotation processor. The generated swagger doc included an extra property called "empty" of type boolean.

It took me a while to minimize this bug but I've narrowed it down Immutables using Guava collections. On a class like

@Value.Immutable
@JsonSerialize(as = ImmutableMyList.class)
public interface MyList {
  List<String> strings();
}

I was getting an extra property on MyList:

MyList:
      type: object
      properties:
        strings:
          type: array
          properties:
            empty:
              type: boolean
          items:
            type: string

but this minimizes further to

import com.google.common.collect.ImmutableList;

@JsonSerialize(as = ItemListImpl.class)
public interface ItemList {
  List<String> getItems();
}

class ItemListImpl implements ItemList {
  @JsonProperty("items")
  public ImmutableList<String> getItems() {
    return ImmutableList.of();
  }
}

has the same problem. It actually starts to make a bit of sense when I discovered

interface MyFakeList<E> extends List<E> {};
public interface ItemList {
  MyFakeList<String> getMyItems();
}

is enough to trigger it as well.

    ItemList:
      type: object
      properties:
        myItems:
          type: array
          properties:
            empty:
              type: boolean
          items:
            type: string

To Reproduce Steps to reproduce the behavior: See code above.

Expected behavior Expected

    ItemList:
      type: object
      properties:
        myItems:
          type: array
          items:
            type: string

Additional context After minimizing, I'm not actually sure if it's a bug or not, and there's easy work-arounds (in Immutables, jdkOnly = true) but it still feels like a bug; a JSON array can't even have properties. But my feelings won't be hurt anymore if you close it as wontfix.

bnasslahsen commented 4 years ago

Hi @chadselph,

springdoc-openapi is built on top swagger-core library. The issue you are reporting is not related to springdoc-openapi: Here is the sample code to reproduce:

ResolvedSchema resolvedSchema = ModelConverters.getInstance()
        .resolveAsResolvedSchema(new AnnotatedType(ItemList.class));
if (resolvedSchema.schema != null) {
    Schema schemaN = resolvedSchema.schema;
    Map<String, Schema> schemaMap = resolvedSchema.referencedSchemas;
    Assert.isNull( schemaMap.get("ItemList").getProperties().get("empty"), "The should be no empty boolean property");
}

There is apparently an existing similar issue: