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

Create slice/map/string fields without pointers (for optional fields)

Open v-byte-cpu opened this issue 3 years ago • 11 comments

Default value for slice/map is nil. So slice/map field will not be serialized if it is not initialized.

I mean from serialization point of view these two structs are the same:

struct {
  GroupKey *[]string `json:"group_key,omitempty"`
}
struct {
  GroupKey []string `json:"group_key,omitempty"`
}

The later version is more convenient to work with..

https://play.golang.org/p/0c0nVaoOPNK

Also the same applies to string type with omitempty json tag.

Pointer to interface *interface{} struct fields are also useless.

v-byte-cpu avatar Dec 19 '20 11:12 v-byte-cpu

That would be good.

yazver avatar Dec 22 '20 07:12 yazver

Also the same applies to string type

Why it applies also to string?

mitar avatar Jan 11 '21 22:01 mitar

@mitar https://play.golang.org/p/0c0nVaoOPNK here you can look at 33-42 lines for small example

v-byte-cpu avatar Jan 11 '21 22:01 v-byte-cpu

Sure, but how would you know for strings if field has been provided and is empty string vs. it has not been provided at all?

mitar avatar Jan 11 '21 23:01 mitar

It makes sense. Maybe then it is better to use x-go-type extended property explicitly for your use case ? Nevertheless I suppose that most programmers almost always use simple string fields for structs (string field with omitempty tag) and your use case is very data specific.

v-byte-cpu avatar Jan 12 '21 10:01 v-byte-cpu

I mean, I completely agree that those pointers seem to be more or less unnecessary, in almost all cases. And pain to work with. But then I also hate when in grpc/protobuf I cannot know if value was provided or not for zero values. Maybe something like that would be even better:

struct {
    GroupKey string `json:"group_key,omitempty"`
    GroupKeyProvided bool `json:-`
}

mitar avatar Jan 12 '21 22:01 mitar

It should be up to the application to decide whether a missing value is equivalent to a zero value. I'd like to propose a solution that works for both cases. The nullable field should control indirection.

Option 1: Binary nullable (true, false)

This is my preference. Missing/false are treated identically. The default value for nullable is false per the OpenAPI 3 spec.

  • required && nullable -> Foo *string `json:"foo"`
  • required && !nullable -> Foo string `json:"foo"`
  • !required && nullable -> Foo *string `json:"foo,omitempty"`
  • !required && !nullable -> Foo string `json:"foo,omitempty"`

Option 2: Ternary nullable (true, false, missing)

Same as option 1, but when absent nullable defaults to `!required (nullable if not required non-nullable if required). This maintains current default behavior as of this writing while still allowing explicit override.


I'm happy to contribute a change for either approach.

ckarenz avatar Aug 13 '21 00:08 ckarenz

I think the first option is better as it is more intuitive to understand. @deepmap-marcinr what do you think ?

v-byte-cpu avatar Aug 13 '21 10:08 v-byte-cpu

Binary nullable is a good option! But I'm sad what it's not implemented yet. Is there any updates since aug?

nsemikov avatar Feb 22 '22 22:02 nsemikov

Is there any chance of merging the PR that is solving this issue?

jfcavalcante avatar Jul 21 '22 17:07 jfcavalcante

Let's make this PR flaggable via the Configuration structure, then it's good to go. Whenever we've made breaking changes, people complain, so let's be nice about it.

I've been away for a while, sorry for tardy responses.

deepmap-marcinr avatar Jul 21 '22 18:07 deepmap-marcinr

Would be awesome, as e.g. https://github.com/uptrace/bun struggles with pointer slices

vennekilde avatar Jul 15 '23 15:07 vennekilde