oapi-codegen icon indicating copy to clipboard operation
oapi-codegen copied to clipboard

Support additionnalProperties: false in OneOf

Open LelouBil opened this issue 3 years ago • 8 comments

~~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

LelouBil avatar Jul 07 '22 14:07 LelouBil

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.

Warboss-rus avatar Jul 27 '22 06:07 Warboss-rus

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.

LelouBil avatar Jul 27 '22 08:07 LelouBil

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)

LelouBil avatar Jul 27 '22 08:07 LelouBil

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

LelouBil avatar Jul 27 '22 08:07 LelouBil

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

LelouBil avatar Jul 27 '22 09:07 LelouBil

Deserialization shouldn't. That's a validation rule which should be handled through evaluation with json schema.

chanced avatar Jul 27 '22 15:07 chanced

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?

enricoribelli avatar Dec 01 '23 13:12 enricoribelli