Skip to content
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: add "inline" struct tag #6213

Open
gopherbot opened this issue Aug 22, 2013 · 44 comments
Open

proposal: encoding/json: add "inline" struct tag #6213

gopherbot opened this issue Aug 22, 2013 · 44 comments

Comments

@gopherbot
Copy link

gopherbot commented Aug 22, 2013

by bjruth:

Discussion was conceived on golang-nuts:
https://groups.google.com/forum/#!topic/golang-nuts/bAgNll-EMkI to add support for a
flag that supports unmarshaling arbitary JSON into structs. A tag was announced for the
mgo/bson package here:
https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/ZeP7PaXVDQo that
transparently stores data into a separate struct field denoted by "inline"
during an unmarshal and then merges that data back into the output during marshaling.

I believe this would be a very useful feature to add into the encoding/json package and
does not introduce any breaking changes in the Go 1.x series.

Edited by @dsnet on 2020-11-10 to fix formatting.

@adg
Copy link
Contributor

adg commented Aug 22, 2013

Comment 1:

I think this is worthwhile. I have an unfinished proposal in my email drafts that is
basically exactly what Gustavo describes in his bson release announcement mail.
It should be simple enough that it could be done before the 1.2 cutoff. Any disagreement?

Labels changed: added priority-soon, go1.2, feature, removed priority-triage.

Owner changed to @adg.

Status changed to Accepted.

@adg
Copy link
Contributor

adg commented Aug 28, 2013

Comment 2:

https://golang.org/cl/13180043

Status changed to Started.

@adg
Copy link
Contributor

adg commented Aug 29, 2013

Comment 3:

This issue was closed by revision 466001d.

Status changed to Fixed.

@adg
Copy link
Contributor

adg commented Aug 29, 2013

Comment 4:

Submitted the CL by mistake.

Status changed to Started.

@adg
Copy link
Contributor

adg commented Aug 29, 2013

Comment 5:

This issue was closed by revision 27f4166.

Status changed to Fixed.

@adg
Copy link
Contributor

adg commented Aug 29, 2013

Comment 6:

And that was the undo CL closing it again :/
New CL https://golang.org/cl/13324045/

Status changed to Started.

@robpike
Copy link
Contributor

robpike commented Sep 3, 2013

Comment 7:

Not going into 1.2.

Labels changed: removed go1.2.

@rsc
Copy link
Contributor

rsc commented Sep 5, 2013

Comment 8:

Not even sure this is worthwhile.

Status changed to Thinking.

@gopherbot
Copy link
Author

gopherbot commented Sep 5, 2013

Comment 9 by bjruth:

@rsc It's not that a manual approach doesn't work, but since the unmarshaler already
handles distinguishing known vs. unknown fields relative to the target interface, the
extra data can thrown into a "catch-all" field.

@rsc
Copy link
Contributor

rsc commented Nov 27, 2013

Comment 10:

Labels changed: added go1.3maybe.

@rsc
Copy link
Contributor

rsc commented Nov 27, 2013

Comment 11:

Labels changed: removed feature.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 12:

Labels changed: added release-none, removed go1.3maybe.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 13:

Labels changed: added repo-main.

@lukescott
Copy link

lukescott commented Mar 1, 2014

Comment 14:

I really need this. I have a struct that has static and dynamic fields. The dynamic
fields (in a map) are chosen by the user and need to be inline with the static ones.

@extemporalgenome
Copy link
Contributor

extemporalgenome commented Apr 25, 2014

Comment 15:

If this is going to be similar to <labix.org/v2/mgo/bson>, ideally an "inline" map
or struct pointer would not be allocated (the field value would remain nil) until there
is something valid to stuff in it.

@gopherbot
Copy link
Author

gopherbot commented May 7, 2014

Comment 16 by relistan:

+1. I was pondering writing a similar thing and came across this. Essentially we query a
3rd party API that is not versioned and changes. Catching the leftovers would let us
better get a sense of what was skipped. At a minimum it's great for debugging.

@gopherbot
Copy link
Author

gopherbot commented Jul 11, 2014

Comment 17 by andrew@happyinspector.com:

+1 I have something where I have a some common fields (id, path, revision, etc) and I
use an anonymous struct that is embedded in other structs. However, I can't implement a
custom json marshal on the common struct as then all the other structs will only return
the output from the marshalled common fields.

@gopherbot
Copy link
Author

gopherbot commented Jul 11, 2014

Comment 18 by andrew@happyinspector.com:

+1 I have something where I have some common fields (id, path, revision, etc) and I use
an anonymous struct that is embedded in other structs. However, I can't implement a
custom json marshal on the common struct as then all the other structs will only return
the output from the marshalled common fields.

@benji-bou

This comment was marked as spam.

@leaxoy

This comment has been minimized.

@mitar
Copy link
Contributor

mitar commented Nov 6, 2020

In #42417 I proposed to have the following syntax:

type Message struct {
  Name  string                 `json:"name"`
  Type  string                 `json:"type"`
  Skip  string                 `json:"-"`
  Extra map[string]interface{} `json:"+"`
}

So + would mark a field into which all extra/unexpected fields would go.

@dsnet
Copy link
Member

dsnet commented Jan 12, 2021

+ is an interesting idea, but the + character is already a valid name, so we cannot use that in a backwards compatible way.

@smoyer64
Copy link

smoyer64 commented Jan 13, 2021

The - character is also a valid name but the encoding/json package lets you use it by adding the json:"-," value. See https://pkg.go.dev/encoding/json#Marshal.

@dsnet
Copy link
Member

dsnet commented Jan 13, 2021

@smoyer64, that's doesn't fix the issue I mentioned:

  • json:- means this field is ignored
  • json:-, means this field is named "-"

However, today:

  • json:+ means this field is named "+"; and we can't redefine the meaning of this
  • json:+, means this field is named "+"

@fdcds
Copy link

fdcds commented Apr 22, 2021

encoding/xml supports this via the xml:",any" tag:

  • If the XML element contains a sub-element that hasn't matched any
    of the above rules and the struct has a field with tag ",any",
    unmarshal maps the sub-element to that struct field.

(https://golang.org/pkg/encoding/xml/#Unmarshal)

Should the same mechanism be used for encoding/json?

@bjg2
Copy link

bjg2 commented Apr 25, 2022

+1.

Having an element that has a field 'type', and different schema depending on the value of that field is pretty much idiomatic way of building JSON objects / arrays. That's the way most APIs work, and it's surprising that golang, which is the language for servers, does not have strong support for such a common usecase.

@parkerroan

This comment was marked as spam.

@zelch
Copy link

zelch commented Aug 29, 2022

I've read through the comments a few times, and I'm confused.

The ticket is still open, is this still an active proposal? Are we waiting for a better suggestion on syntax / naming?

@smoyer64
Copy link

smoyer64 commented Aug 29, 2022

At this point, I'd be happy to have ANY solution - the work-arounds are killers!

@zelch
Copy link

zelch commented Oct 21, 2022

@dsnet Ping on my question above.

What is the current status of this? 9 years later, and this is still an issue for many of us.

I would be perfectly happy to work on the issue, but since I am not sure what the current blocking point is, I'm not sure where to go from here.

Requiring that the 'inline' struct tag have either a blank name, or one of '-' or '+', plus the 'any' tag, so something like ",any", "-,any", or even "+,any" seems like it would get past all of the issues regarding simply using - or + as the only indicator.

Using 'any' seems to make sense, as that is used by the XML encoder, but I'm happy with another keyword if that is preferred.

@n-bruno
Copy link

n-bruno commented Oct 23, 2022

If I'm reading the thread correctly, this was implemented by adg earlier in the thread here but was never accepted. The tag added was overflow.

I think it's a feature worth adding as leveraging embedding (anonymous field) won't always work, as I've encountered recently with generics.

@zelch
Copy link

zelch commented Oct 23, 2022

Hi @n-bruno.

As best as I can tell, that change was merged by accident, backed out... And then never revisited, at least as far as I can tell.

In my case, what I really want to do is embed a map of additional arbitrary JSON key/value pairs, which, of course, also isn't possible with embedding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Hold
Development

No branches or pull requests