-
-
Notifications
You must be signed in to change notification settings - Fork 806
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider adding Nullable
wrapper for non-required nullable properties
#1039
Comments
Similar to #1061 If the field is set to |
Consider for example a resource that maybe looks like:
When designing a
In this model knowing that B was unspecified allow us to avoid updating it while procesing the request. If we do want to set B to null, we could send:
Basically, there is difference in JSON between null and undefined (its also why go's map lookup has the |
Is this addressed by #1102 being completed? 👀 |
I might be mis-understanding, but I don't think it changes the problem. Consider this field:
Which turned into this member in the input struct with 1.15.0:
Passing null in the json body results in an empty string in the EDIT: Actually, its slightly more than that, I cant distinguish between null, undefined or empty string. |
@emarcotte as for me your definition should yield a pointer to string. I've been trying to solve similar issue and unable to come up with solution in current state of generator (models and client). In case As go lacks of a null-undefined distinction (thank goodness), I think it's justified to combine these two if it is configured so. |
This is true when considering a struct with attributes, but it is not true if you consider that jsonschema is describing Go itself does understand the difference between undefined and nil when it comes to
Which will output the 3 different states rather than aliasing nil and undefined together, something like:
To me, this is exactly describing the semantics described with an object with not-required-but-nullable fields. Coming back to openapi-codegen, my basic idea here is to come up with a standardized way to document an object structure that has attributes that may not be provided. The approach I describe with a generic Optional type works, but it's in my own repo and has to be copied into any other projects. I'm willing to provide PRs if there is interest, if there's not I'll just leave it on my own repos. |
With maps - yes, it is true, but not true with structures, and we usually operate with structures. My team actually sitting on own fork of this library but v2 forced to perform migration and I wanted to try to do as less changes to generator as possible this time by slightly changing spec generation (we generate spec from code). Basically we have pretty simple logic -
Thats it =) |
An example of the use of wrapper types in ogen (another Go OpenAPI code generator tool): https://github.com/ogen-go/ogen#generics. |
Hey folks, apologies for missing the last few messages. Current stateIf we have: Obj:
properties:
field_name:
type: string
required: [field_name] Would generate: type Obj struct {
FieldName string // JSON tags omitted
} And if we make it optional: Obj:
properties:
field_name:
type: string Would generate: type Obj struct {
FieldName *string // JSON tags omitted
} Proposed
Right now, Obj:
properties:
field_name:
# NOTE: this would be supported via OpenAPI 3.1
# type: [string, 'null']
# NOTE: this only works for OpenAPI 3.0.x
type: string
nullable: true And generate: type Nullable[T any] struct {
Value T
Set bool
Null bool
}
// TODO: Implement custom `MarshalJSON` and `UnmarshalJSON`
type Obj struct {
FieldName Nullable[string] // JSON tags omitted
} Would that be a suitable solution? This must be opt-in via a flag in |
Seems viable on a quick glance. |
Optional
wrapper for non-required nullable propertiesNullable
wrapper for non-required nullable properties
Looks like we can do with type Nullable[T any] struct {
Value *T
Set bool
} If Set is true -- this means a value was provided in JSON ( even an explicit null ) |
Worth confirming if this is something that may be made easier by golang/go#63397 |
We have spun out a separate package, `oapi-codegen/nullable` as a step towards oapi-codegen/oapi-codegen#1039. Until we have implemented oapi-codegen#27, we cannot add an explicit type alias in this package, so we can at least add some tests to cover additional functionality and expectations that the package should have when interplaying with `oapi-codegen`. Co-authored-by: Sebastien Guilloux <sebastien.guilloux@elastic.co> Co-authored-by: Ashutosh Kumar <ashutosh.kumar@elastic.co>
We have spun out a separate package, `oapi-codegen/nullable` as a step towards oapi-codegen/oapi-codegen#1039. Until we have implemented oapi-codegen#27, we cannot add an explicit type alias in this package, so we can at least add some tests to cover additional functionality and expectations that the package should have when interplaying with `oapi-codegen`. Co-authored-by: Sebastien Guilloux <sebastien.guilloux@elastic.co> Co-authored-by: Ashutosh Kumar <ashutosh.kumar@elastic.co>
As part of oapi-codegen#1039, we've created a new library `oapi-codegen/nullable`, which allows tracking whether: - a field is not sent - a field is sent with an explicit `null` - a field is sent with an explicit value This introduces an opt-in `output-options` flag, `nullable-type`, which can generate the `nullable.Nullable` types. This is opt-in, as existing code will break due to the signature change, as well as a behaviour change. Closes oapi-codegen#1039. Co-authored-by: Ashutosh Kumar <ashutosh.kumar@elastic.co>
As part of oapi-codegen#1039, we've created a new library `oapi-codegen/nullable`, which allows tracking whether: - a field is not sent - a field is sent with an explicit `null` - a field is sent with an explicit value This introduces an opt-in `output-options` flag, `nullable-type`, which can generate the `nullable.Nullable` types. This is opt-in, as existing code will break due to the signature change, as well as a behaviour change. Closes oapi-codegen#1039. Co-authored-by: Ashutosh Kumar <ashutosh.kumar@elastic.co>
When using the "strict" server types for a simple object definition like:
It renders to something like:
This construction does not naturally let you determine if the field
hello
was included in a payload or if it was explicitly set to null.The current best work around I can see for dealing with this is to set x-go-type to a json.RawMessage and define my own wrapper struct containing an
Optional[string]
as described here:https://stackoverflow.com/questions/36601367/json-field-set-to-null-vs-field-not-there
Would it be reasonable to add a configurable alternative to generate something like this automatically so that both null and absent can be detected in a strict server?
The text was updated successfully, but these errors were encountered: