oapi-codegen
oapi-codegen copied to clipboard
Support additionnalProperties: false in OneOf
~~If I have an openApi schema that has additionalProperties: false, and I send a request with extra fields, it should be refused.~~.
After more research, I found out this is the job of the request validator. But It doesn't change what happens about OneOf.
For methods like AsSomeType() generated in case of a OneOf
Is currently deserialized like this :
var body MyElement
err := json.Unmarshal(t.union, &body)
return body, err
And it should be deserialized like this (if the target schema has additionalProperties set to false) :
var body MyElement
dec := json.NewDecoder(bytes.NewReader(t.union))
dec.DisallowUnknownFields()
err := dec.Decode(&body)
return body, err
This change will break anyOf, which is handled by the same code and extracts partial data from union. Also, ignoring unknown fileds is useful for backwards compatibility, as we can add new fields without using entirely new API version, so making it default to fail is not a good idea. And finally, it is a breaking change, since it will also disallow unknown fields in all underlying objects, not just the top level of union object. If you really need it, I think it should be an option that is off by default.
Well, I (sort of) solved my actual problem an other way.
My actual problem was that I had a base schema, a second schema extending the first one using allOf, and a third schema that is a oneOf that could be either the base or the extended.
I had put additionalProperties: false in both the base and the extended.
My actual problem was that AsBase() never returned an error because the additionalProperties was not being used.
I don't know if that's a propre use of additionalProperties, but in the end I solved my problem using the ValueByDiscriminator method, which I discovered later because it was not being generated with my spec at first.
Regarding this actual issue I think the deserialization should honor the additionalProperties value if the oneOf variant (I'm not sue how that should be done according to the OpenApi spec)
The current default configuration for the Java client of the Openapi Generator (which I am using on the other side of my application) is currently configured to honor additionalProperties during oneOf matching searching :
https://github.com/OpenAPITools/openapi-generator/blob/b6ca40031a6225441a627cb5a311eff4c9d5eeef/modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/pojo.mustache#L437-L457
https://github.com/OpenAPITools/openapi-generator/blob/32d15100b0622c5e57ac131615e057a58aecef8e/modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/oneof_model.mustache#L101-L112
The oneOf class calls validateJsonObject successfully on the possible matches, and validateJsonObject is set up to fail if an extra property is present while additionalProperties is set to false
In fact, I even just found out they disallow extra fields by default unless additionalProperties is explicitely set to true.
https://github.com/OpenAPITools/openapi-generator/blob/b6ca40031a6225441a627cb5a311eff4c9d5eeef/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java#L264-L266
Deserialization shouldn't. That's a validation rule which should be handled through evaluation with json schema.
Well, I (sort of) solved my actual problem an other way.
My actual problem was that I had a base schema, a second schema extending the first one using allOf, and a third schema that is a oneOf that could be either the base or the extended.
I had put additionalProperties: false in both the base and the extended.
My actual problem was that AsBase() never returned an error because the additionalProperties was not being used.
I don't know if that's a propre use of additionalProperties, but in the end I solved my problem using the ValueByDiscriminator method, which I discovered later because it was not being generated with my spec at first.
I am having the same problem that the ValueByDiscriminator method (and others that should appear when using anyOf in the schema) is not being generated. How did you make it happen?