-
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: allow returning nil from MarshalJSON to omit the field #50480
Comments
I worry this could result in an accidental omission. How about |
What is the state for this, would a PR for this be accepted? I really like the |
I just saw this comment is created from one of the ideas #11939, explicitly for |
@mitar what happens if type Nil struct{}
func (Nil) MarshalJSON() ([]byte, error) {
return nil, nil
}
func main() {
data, _ := json.Marshal(Nil{})
fmt.Println(string(data)) // what's the expected output?
} |
@mitar I implemented your idea here https://github.com/icholy/json if you want to play with it https://go.dev/play/p/7Cf6BgrNGpP edit: I've also implemented the type MarshalNil struct{}
func (MarshalNil) MarshalJSON() ([]byte, error) {
return []byte("null"), json.ErrEmpty
} This type will marshal to |
Regarding #50480 (comment) Wouldn't |
This proposal is a duplicate of a previously discussed proposal, as noted above, |
Sorry, where exactly has this already been discussed? So I found a mention in one long issue (on |
Hm, I saw that one, but I disagree that this one would be addressed with |
Currently even if one implements
MarshalJSON
on a struct there is no way to prevent its inclusion into the parent struct. E.g.:(Full example: https://go.dev/play/p/A0wKfuZgURw)
The best one can do is return
null
. But what if one wants to fully omit the field? This is not possible. Or one has to implementMarshalJSON
on the parent struct, but that is not nice from composability perspective (one would have to implement this for every struct which includesField
).I propose that it should be allowed to return
nil, nil
fromMarshalJSON
to signal that the field should be omitted in the parent struct. Currently returningnil, nil
does fails with errorunexpected end of JSON input
because the resulting JSON is malformed. That means that nobody can rely on this behavior really for correct JSON output (maybe only to catch errors?), so I do not think we would be breaking any real backwards compatibility if we introduce this, or at least I believe benefits are bigger here. In any case, if you want previous behavior, you can return[]byte{}
and then it will continue to error in the same way. Doing JSON marshal of a struct itself which returnsnil
is compatible enough in my view: if caller just assumes they are getting[]byte
slice,nil
will mostly behave for them as an empty slice. If they are able to handle it anyway.Implementing this would also provide a solution for the issue that
omitempty
does not work with structs: one could implementMarshalJSON
which checks if the value is zero and returnnil
if it is so. This would be useful only when implementor of the type is the user of it at the same time, but one can always make a new type as a user and then implementMarshalJSON
there. I think it is an useful step in addressing that.Returning
nil
to omit the field seems to be also something others expected to work and has been also proposed in the past, but inside a bigger discussion, so this can serve as a proposal for just this feature.The text was updated successfully, but these errors were encountered: