-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
proposal: encoding/json: "nonil" struct tag to marshal nil slices and maps as non-null #27589
Comments
For slices and maps, it should be noted that the proposed struct tag is mutually exclusive to |
Here is my pull request. I hope it gets accepted because I believe it adds value to the "Go" programming language. |
I called the struct tag: |
"heed" is a unique word, at least in terms of Go's existing API. If this is accepted (once it's reviewed together with all the existing JSON proposals), I suspect we'd want to change "heed" to something else. |
I scoured the dictionary and thesaurus for appropriate words that were short and exemplified the intention but couldn't find anything. Hopefully a better word can be found because I was initially hesitant of the word too - although admittedly it is growing on me. |
@bradfitz Any idea of the timeframe to when all the JSON proposals will be examined? Some of them are now 2+ years. The pivotal proposal is 7+ years. |
For Go2, |
Will add this to my JSON scan for this cycle. |
Maybe |
|
Seems like precisely the right word. It's not part of the Go vocabulary, but it seems like a great addition in various future contexts for programming languages in general. eg. heed memory, heed security etc |
heednull means "pay attention to null" by not respecting that the value is null and instead printing something other than "null"? That seems backward to me. |
If it was called I then went from that step to Perhaps due to the confusion, and ambiguity, |
On hold for JSON sweep. |
What does that mean? |
The The "JSON sweep" is a sweep through all the JSON proposal trying to come up with a comprehensive yay/nay to each proposal in an effort to balance features desired with not adding too much technical debt. |
This fork (which sadly I can't use because AppEngine doesn't have sync.Map, it seems) sets an encoder-wide option instead of using a struct tag. It feels to me that either an entire system is fine with having |
@tommie in my opinion the problem is that any system doesn't work in isolation. Complex software has complex integrations with different technologies and different expectations. Global flag is not versatile enough. |
That is a non-answer, IMHO (and somewhat belittling). I can see different complex software requiring different options, and AFAIK, this thread has not discussed the already existing solution yet.
Defining what the default behavior is could still be an encoder option, while allowing per-field overrides. The two solutions are not mutually exclusive. The problem I'm trying to solve is interoperability with Javascript. Passing |
Change https://golang.org/cl/136761 mentions this issue: |
I provide an explanation in the similar issue here #37711 why I think a tag is not the right way to address this problem even in a third-party package. |
…fix nil error in encoding/json. golang/go#27589 (comment)
Any progress on this, this is a great proposal. |
@leaxoy see #27589 (comment). We'll update the many json proposals when we have news. Don't hold your breath because it's a big project, but it's in progress. Until then, asking for progress or an ETA won't really help. |
is there any other approach currently for this one? |
Javascript really does not like to get a null when it expects an empty array, but that's what Go will send if your struct contains e.g. a []string and you don't explicitly initialize the slice. These custom marshallers make sure we send an empty array, making the frontend's life easier. Go desperately needs some way to tell the JSON encoder that we want this behavior, see: golang/go#37711 golang/go#27589 golang/go#27813
I just wrote this little package, which recursively initializes all https://github.com/golang-cz/nilslice Might be useful for some, until we have a proper solution merged to import "github.com/golang-cz/nilslice" type Payload struct {
Items []Item `json:"items"`
}
payload := &Payload{}
b, _ = json.Marshal(nilslice.Initialize(payload))
fmt.Println(string(b))
// {"items": []} |
… in JSON Golang issue: golang/go#27589 This option will enforce server to encode nil slices as empty arrays in JSON. This is helpful mainly in JavaScript and TypeScript clients, where a response field of type array should never be assigned to `null` value.. Example: func (s *Server) GetItems(ctx context.Context) ([]*Items, error) { var items []*Item // Will send {"items": []} in JSON response instead of {"items": null}. return items, nil }
… in JSON Golang issue: golang/go#27589 This option will enforce server to encode nil slices as empty arrays in JSON. This is helpful mainly in JavaScript and TypeScript clients, where a response field of type array should never be assigned to `null` value.. Example: func (s *Server) GetItems(ctx context.Context) ([]*Items, error) { var items []*Item // Will send {"items": []} in JSON response instead of {"items": null}. return items, nil }
… in JSON (#32) Golang issue: golang/go#27589 This option will enforce server to encode nil slices as empty arrays in JSON. This is helpful mainly in JavaScript and TypeScript clients, where a response field of type array should never be assigned to `null` value.. Example: func (s *Server) GetItems(ctx context.Context) ([]*Items, error) { var items []*Item // Will send {"items": []} in JSON response instead of {"items": null}. return items, nil }
Until go JSON marshalling supports golang/go#27589, initialising a slice is the only way to marshal empty arrays into JSON instead of null values.
Hi all, we kicked off a discussion for a possible "encoding/json/v2" package that addresses the spirit of this proposal. For flexibility, it provides the ability to alter this behavior with:
|
Based on this idea I've prepared more complex solution: The same applies for |
There have been many reports about encoding a nil slice or map as
[ ]
or{ }
respectively.See: #2278
Currently it is encoded as
null
. This is a source of bugs in many non-theoretical cases (eg consumers of JSON APIs). There are many issues on Google about others falling into this pitfall so it is at least not uncommon.It would be nice if a struct tag can be used to signify that we intend the nil slice or map to be treated as an empty slice or map respectively for the purposes of marshalling.
Current solutions include: https://github.com/helloeave/json. This is not a nice solution because it requires the assistance of a third-party package.
This is how it's implemented in third party lib: homelight/json@7b6e442
My PR can be found here: #27813 (subject to an agreed struct tag name, which when decided, can be updated in the PR)
The text was updated successfully, but these errors were encountered: