OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
[ ] [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description
Using 7.0.0-beta of the openapi-generator-maven-plugin (library = spring-boot):
Enum Type as discriminator feature https://github.com/OpenAPITools/openapi-generator/pull/13846 (oneOf interface polymorphism) ignores modelNameSuffix specified in the plugin configurations when generating the abstract get{Discriminator}() method for the interface, but is considering it while generating the enum and concrete class' relevant discriminator field and set/get methods. This results in a compile time error (incompatible types).
Presume this is an issue for modelNamePrefix as well.
Generated Discriminator Enum, Interface and Concrete classes
Enum:
@Generated(value = "org.openapitools.codegen.languages.SpringCodegen")
public enum FruitTypeDto {
APPLE("APPLE"),
BANANA("BANANA");
private String value;
FruitTypeDto(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
@Override
public String toString() {
return String.valueOf(value);
}
@JsonCreator
public static FruitTypeDto fromValue(String value) {
for (FruitTypeDto b : FruitTypeDto.values()) {
if (b.value.equals(value)) {
return b;
}
}
throw new IllegalArgumentException("Unexpected value '" + value + "'");
}
}
Interface:
@JsonIgnoreProperties(
value = "fruitType", // ignore manually set fruitType, it will be automatically generated by Jackson during serialization
allowSetters = true // allows the fruitType to be set during deserialization
)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "fruitType", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Apple.class, name = "APPLE"),
@JsonSubTypes.Type(value = Apple.class, name = "Apple"),
@JsonSubTypes.Type(value = Banana.class, name = "BANANA"),
@JsonSubTypes.Type(value = Banana.class, name = "Banana")
})
@Generated(value = "org.openapitools.codegen.languages.SpringCodegen")
public interface Fruit {
public FruitType getFruitType();
}
Concrete class (Banana is generated the same considering the model suffix)
@Generated(value = "org.openapitools.codegen.languages.SpringCodegen")
public class Apple implements Fruit {
private Integer seeds;
private FruitTypeDto fruitType;
public Apple() {
super();
}
/**
* Constructor with only required parameters
*/
public Apple(Integer seeds) {
this.seeds = seeds;
this.fruitType = fruitType;
}
public Apple seeds(Integer seeds) {
this.seeds = seeds;
return this;
}
/**
* Get seeds
* @return seeds
*/
@NotNull
@Schema(name = "seeds", requiredMode = Schema.RequiredMode.REQUIRED)
@JsonProperty("seeds")
public Integer getSeeds() {
return seeds;
}
public void setSeeds(Integer seeds) {
this.seeds = seeds;
}
public Apple fruitType(FruitTypeDto fruitType) {
this.fruitType = fruitType;
return this;
}
/**
* Get fruitType
* @return fruitType
*/
@NotNull @Valid
@Schema(name = "fruitType", requiredMode = Schema.RequiredMode.REQUIRED)
@JsonProperty("fruitType")
public FruitTypeDto getFruitType() {
return fruitType;
}
public void setFruitType(FruitTypeDto fruitType) {
this.fruitType = fruitType;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Apple apple = (Apple) o;
return Objects.equals(this.seeds, apple.seeds) &&
Objects.equals(this.fruitType, apple.fruitType);
}
@Override
public int hashCode() {
return Objects.hash(seeds, fruitType);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class Apple {\n");
sb.append(" seeds: ").append(toIndentedString(seeds)).append("\n");
sb.append(" fruitType: ").append(toIndentedString(fruitType)).append("\n");
sb.append("}");
return sb.toString();
}
/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private String toIndentedString(Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}
if one wants to leverage oneOf which generates Interface and concrete classes: don't configure modelNameSuffix/modelNamePrefix
if one wants to keep the modelNameSuffix/Prefix: Leverage composition instead--> Generate base concrete class and subclasses by removing oneOf and specify allOf in the child schemas. The resulting generated code retains the DTO in the base concrete model class.
Thanks @quesojeany for reporting the bug. I am also facing the same issue. <modelNameSuffix>Dto</modelNameSuffix>stopped working after upgrading plugin version to "7.0.0-beta"
Bug Report Checklist
Description
Using 7.0.0-beta of the openapi-generator-maven-plugin (library = spring-boot):
Enum Type as discriminator feature https://github.com/OpenAPITools/openapi-generator/pull/13846 (oneOf interface polymorphism) ignores modelNameSuffix specified in the plugin configurations when generating the abstract get{Discriminator}() method for the interface, but is considering it while generating the enum and concrete class' relevant discriminator field and set/get methods. This results in a compile time error (incompatible types).
Presume this is an issue for modelNamePrefix as well.
openapi-generator version
7.0.0-beta
OpenAPI declaration file content or url
Yaml:
Generation Details
Maven plugin (the bits that matter):
Generated Discriminator Enum, Interface and Concrete classes
Enum:
Interface:
Concrete class (Banana is generated the same considering the model suffix)
Steps to reproduce
Related issues/PRs
https://github.com/OpenAPITools/openapi-generator/pull/13846
Suggest a fix/workaround
current workarounds:
sample yaml for option two workaround