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

encoding/json: json.RawMessage does not works correctly #35992

Closed
gromas opened this issue Dec 5, 2019 · 7 comments
Closed

encoding/json: json.RawMessage does not works correctly #35992

gromas opened this issue Dec 5, 2019 · 7 comments

Comments

@gromas
Copy link

@gromas gromas commented Dec 5, 2019

I want to unmarshal JSON to different struct types and I write:

	bytes := []byte(`
		{"__type":"instance.started","InstanceId":"a9ff34dd-d20b-4887-99d6-f2f3a68f86a5"}
	`)
	var envelope struct {
		Type string `json:"__type"`
		Json *json.RawMessage
	}

        _ = json.Unmarshal(bytes, &envelope)

	fmt.Println(envelope.Type)
	fmt.Println(envelope.Json)

I get empty envelope.Json but must be an byte array (json.RawMessage).

repro:
https://play.golang.org/p/m6wd44R35FZ

@ALTree

This comment was marked as outdated.

Copy link
Member

@ALTree ALTree commented Dec 5, 2019

Hi,

matching is based on field names and annotations.

From the Json and Go post:

For a given JSON key "Foo", Unmarshal will look through the destination struct's fields to find (in order of preference):

  • An exported field with a tag of "Foo" (see the Go spec for more on struct tags),
  • An exported field named "Foo", or
  • An exported field named "FOO" or "FoO" or some other case-insensitive match of "Foo".

So you need to change your struct to either

	var envelope struct {
		Type string `json:"__type"`
		InstanceId *json.RawMessage
	}

or

	var envelope struct {
		Type string `json:"__type"`
		Json *json.RawMessage `json:"InstanceId"`
	}

Closing here, since this is not a bug.

@ALTree ALTree closed this Dec 5, 2019
@gromas

This comment has been minimized.

Copy link
Author

@gromas gromas commented Dec 5, 2019

Hey! Thank you for answer. InstanceId is sample field. I have over 100 different message types and want to reflect json to different golang structs (I use switch evnvelope.Type ... json.Unmarshal(envelope.Json, &concreteType)...) I don't want json:"InstanceId"

And this is a bug with json.RawMessage

@ALTree

This comment has been minimized.

Copy link
Member

@ALTree ALTree commented Dec 5, 2019

EDIT: yeah misread. Re-opening.

@ALTree ALTree reopened this Dec 5, 2019
@ALTree ALTree added WaitingForInfo and removed WaitingForInfo labels Dec 5, 2019
@gromas

This comment has been minimized.

Copy link
Author

@gromas gromas commented Dec 5, 2019

Same problem with marshaling. I marshal {Type, some_message} data and get some_message only without __type ))

https://play.golang.org/p/SsgQmtq2yP0

@toothrot toothrot changed the title json.RawMessage does not works correctly encoding/json: json.RawMessage does not works correctly Dec 5, 2019
@toothrot

This comment has been minimized.

Copy link
Contributor

@toothrot toothrot commented Dec 5, 2019

Hi @gromas,

Referring to your first example:

	bytes := []byte(`
		{"__type":"instance.started","InstanceId":"a9ff34dd-d20b-4887-99d6-f2f3a68f86a5"}
	`)
	
	var envelope struct {
		Type string `json:"__type"`
		Json *json.RawMessage
	}

What exactly do you expect to appear in the Json struct field?

@seankhliao

This comment has been minimized.

Copy link
Contributor

@seankhliao seankhliao commented Dec 5, 2019

@gromas
The go struct structure has to match the json structure, you cannot just dump all the unrecognized fields into a json.RawMessage
What you can do is unmarshal twice, once to find the type, second time into a known struct. json.RawMessage is for making this more convenient in more deeply nested structs

Your second example you are embedding a json.RawMessage whose MarshalJSON/UnmarshalJSON is being promoted to envelope and overriding the marshal process

@toothrot

This comment has been minimized.

Copy link
Contributor

@toothrot toothrot commented Dec 9, 2019

Thanks @seankhliao. I'm going to close this issue, as it is not clear that this is a bug. @gromas, please see one of the resources on https://golang.org/wiki/Questions for further help using the encoding/json package.

@toothrot toothrot closed this Dec 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.