europace / baufismart-kundenangaben-api

API zum Importieren von Kundenangaben in einen neuen Vorgang in BaufiSmart.
https://developer.europace.de
14 stars 4 forks source link

swagger-codegen-3.0.18 hat Probleme mit der Variable @type #112

Open KDingeling opened 3 years ago

KDingeling commented 3 years ago

Moin,

wir generieren das Datenmodell anhand der kundenangaben-openapi.json mit swagger-codegen-3.0.18, dabei tritt offenbar ein Bug im Generator mit der Variable @type auf. Hier nehme ich mal als Beispiel den Familienstand, es betrifft aber alle Objekte, in denen @type required ist.

@Schema(description = "Mögliche Typen: Ledig, Verheiratet, Verwitwet, Geschieden, GetrenntLebend, Lebenspartnerschaft")
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type", visible = true )
@JsonSubTypes({
  @JsonSubTypes.Type(value = Ledig.class, name = "Ledig"),
  @JsonSubTypes.Type(value = Geschieden.class, name = "Geschieden"),
  @JsonSubTypes.Type(value = Verheiratet.class, name = "Verheiratet"),
  @JsonSubTypes.Type(value = Lebenspartnerschaft.class, name = "Lebenspartnerschaft"),
  @JsonSubTypes.Type(value = GetrenntLebend.class, name = "GetrenntLebend"),
  @JsonSubTypes.Type(value = Verwitwet.class, name = "Verwitwet"),
})

public class Familienstand {
  @JsonTypeId
  private String _atType = null;

  public Familienstand _atType(String _atType) {
    this._atType = _atType;
    return this;
  }
  ...
}
public class Ledig extends Familienstand implements OneOfPersonendatenFamilienstand {
    ...
}

Wenn ich es richtig verstehe, müsste für die Variable _atType in Familienstand eigentlich die Annotation @JsonProperty("@type") generiert werden. Das passiert aber nicht und führt dann beim Aufruf der API zu Fehlern. Ich setze den _atType nach Erzeugen der Instanz selbst, da das vom Generator nicht in der Klasse Ledig selbst erledigt wird.

    private OneOfPersonendatenFamilienstand mapMaritalStatus(final MaritalStatus maritalStatus) {
        switch (maritalStatus) {
            case LEDIG:
            case SINGLE:
                final var ledig = new Ledig();
                ledig.setAtType("LEDIG");
                return ledig;
        ...
        }
    }
    private Personendaten mapPersonendaten(final ApplicantRequestResource applicant) {
        final var personendaten = new Personendaten();
        ....
        Optional.ofNullable(applicant.getMaritalStatus()).ifPresent(maritalStatus -> personendaten.setFamilienstand(mapMaritalStatus(maritalStatus)));
        ...
        return personendaten;
    }

Wenn ich das so abschicke, gibt mir der Bodyvalidation Endpunkt folgendes zurück:

400 BAD_REQUEST - Cannot deserialize into kundenangaben.haushalte.[0].kunden.[0].personendaten.familienstand: @type is missing

Ich bin nicht sicher, wie ich das Problem lösen kann, ohne in den generierten Klassen Änderungen vorzunehmen, die dann bei einem Update des Modells wieder überschrieben werden würden. Habt ihr dazu vielleicht eine Idee?

Ich habe auch schon neuere Versionen von swagger-codegen probiert, dort tritt das selbe Verhalten auf.

KDingeling commented 3 years ago

Kurzes Update:

Wenn ich die generierte Klasse wie unten anpasse, kann ich den Request erfolgreich an die API senden. Irgendwas scheint dazu zu führen, dass bei Verwendung der Subtypes @type nicht im JSON landet.

@Schema(description = "Mögliche Typen: Ledig, Verheiratet, Verwitwet, Geschieden, GetrenntLebend, Lebenspartnerschaft")
//@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@type", visible = true)
//@JsonSubTypes({
//  @JsonSubTypes.Type(value = Ledig.class, name = "Ledig"),
//  @JsonSubTypes.Type(value = Geschieden.class, name = "Geschieden"),
//  @JsonSubTypes.Type(value = Verheiratet.class, name = "Verheiratet"),
//  @JsonSubTypes.Type(value = Lebenspartnerschaft.class, name = "Lebenspartnerschaft"),
//  @JsonSubTypes.Type(value = GetrenntLebend.class, name = "GetrenntLebend"),
//  @JsonSubTypes.Type(value = Verwitwet.class, name = "Verwitwet"),
//})

public class Familienstand {
//  @JsonTypeId
  @JsonProperty("@type")
  private String _atType = null;
}
KDingeling commented 3 years ago

Wird es noch Anpassung an der Json/Yaml-Spezifikation geben, damit das generierte Datenmodell in Java funktioniert? Die Info würde bei der Planung sehr helfen, da ich den Aufwand für das Schaffen von Workarounds ansonsten mit berücksichtigen muss.

ElisaBaum commented 3 years ago

Hallo @KDingeling,

generell übernehmen wir keinen Support für Code Generatoren.

Es sind erstmal keine Anpassungen an der Json/Yaml-Spezifikation geplant.

Gleichzeitig benutzen wir intern dieselbe Version von swagger-codegen und kommen zu demselben Ergebnis. Allerdings scheint es beim Deserialisieren kein Problem zu sein. Ich prüfe das gerade noch.

Ansonsten könnte ein Mixin im ObjectMapper das Problem der fehlenden @JsonProperty-Annotation beheben. Dann müssten zumindest die generierten Klassen nicht verändert werden.

public abstract class TypeMixin {

  @JsonProperty("@type")
  String _atType;
}
ObjectMapper mapper = new ObjectMapper();
mapper.addMixInAnnotations(Familienstand.class, TypeMixin.class);