swagger-codegen-generators
swagger-codegen-generators copied to clipboard
[Java] Issue with OneOf types
If we have an API definition like so:
components:
schemas:
Foo:
type: object
properties:
foo:
type: string
Bar:
type: object
properties:
bar:
type: string
Schema:
oneOf:
- $ref: '#/components/schemas/Foo'
- $ref: '#/components/schemas/Bar'
Swagger will generate an interface OneOfSchema
, as well as 3 implementors: Schema
, Foo
, Bar
.
The problem is that the APIs (and models) will refer to the empty stub class Schema
, e.g.:
public Schema somethingGet(Schema body) throws ApiException {...}
The problem is you when you call this you get issues, e.g.:
var foo = new Foo();
...
api.somethingGet(foo); //doesn't compile because Foo is not a Schema.
The fix is to rename the interface to be Schema
and only have 2 implementors: Foo
, Bar
.
I had a go at doing this myself, seems like a change to subclass SchemaHandler.processComposedSchema()
for java so that it's like so:
@Override
protected CodegenModel processComposedSchema(CodegenModel codegenModel, ComposedSchema composedSchema, Map<String, CodegenModel> allModels) {
List<Schema> schemas = composedSchema.getOneOf();
//Give the composedModel the same name as the parent:
CodegenModel composedModel = this.createComposedModel(codegenModel.getName(), schemas);
if (composedModel == null) { //returns null if it's not OneOf
schemas = composedSchema.getAnyOf();
composedModel = this.createComposedModel(ANY_OF_PREFFIX + codegenModel.getName(), schemas);
if (composedModel == null) {
return null;
}
}
this.addInterfaceModel(codegenModel, composedModel);
this.addInterfaces(schemas, composedModel, allModels);
//This is a dirty way of saying we don't want to generate the original model
codegenModel.setClassname("X"+codegenModel.classname);
codegenModel.setName("X"+codegenModel.name);
return composedModel;
}