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

Support capturing nested unknown fields #15

Closed
avivpxi opened this issue Aug 21, 2022 · 5 comments · Fixed by #17
Closed

Support capturing nested unknown fields #15

avivpxi opened this issue Aug 21, 2022 · 5 comments · Fixed by #17
Assignees
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed

Comments

@avivpxi
Copy link
Collaborator

avivpxi commented Aug 21, 2022

Following the discussion on this issue, we want to be able to capture unknown fields in nested objects.

@avivpxi
Copy link
Collaborator Author

avivpxi commented Aug 21, 2022

After resolving 12, this playground link produces the following output:

err: <nil>
map: map[known:foo nested:{Known:goo} unknown:boo]
struct: &{Known:foo Nested:{Known:goo}}

meaning, nested object fields contain concrete structs instead of map[string]interface{}, and thus they cannot contain unknown fields (map: map[known:foo nested:{Known:goo} unknown:boo], in out example).

Here, I presented a possible solution to optionally require all nested objects in the map to be maps as well. After thinking about it again I'm not sure this is very usable. Let's take @andeke07 use case presented here, to iterate the eventInfo we will need:

result, _ := marshmallow.Unmarshal(body, &incoming)
data := result["eventInfo"]
dataMap, ok := data.(map[string]interface{})
if ok {
  for key := range dataMap {
    // ...
  }
}

Since we have to lookup and cast, this is not aligning with what Marshmallow tries to provide.
I can think of an alternative solution, allowing nested structs to customize how they handle map data by implementing a HandleJSONData method:

type IncomingMessage struct {
	AlertSummary        string         `json:"alert_summary" validate:"required"`
	DetailedDescription string         `json:"detailed_description" validate:"required"`
	DeviceName          string         `json:"deviceName" validate:"required"`
	EventMetaData       *EventMetaData `json:"eventInfo" validate:"required"`
	Options             struct {
		AffectedCi   string `json:"affected_ci"`
		AffectedArea string `json:"affected_area"`
		HelpURL      string `json:"help_url"`
	} `json:"options"`
}

type EventMetaData struct {
	EventType string `json:"eventType" validate:"required"`
}

func (e *EventMetaData) HandleJSONData(data map[string]interface{}) {
	for key := range data {
		// ...
	}
}

@avivpxi
Copy link
Collaborator Author

avivpxi commented Aug 21, 2022

@andeke07 would that be convenient/usable?

@andeke07
Copy link

@avivpxi thanks for this and also sorry for not replying on my other issue - I was away and not getting any email updates so I missed it. That looks like an interesting approach. So unknown fields in the root of the JSON would show up in the produced map, and unknown nested fields would be acted on via this method?

@avivpxi
Copy link
Collaborator Author

avivpxi commented Aug 21, 2022

@andeke07 no worries 😎
That was my thought, yes.
Actually, if the root object implements HandleJSONData it will also get called but you would be able to get them directly from the Unmarshall call like you do today.

Any other ideas?
Obviously, feel free to open a PR if you like to contribute. 🙏

@avivpxi avivpxi added enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed labels Aug 22, 2022
@avivpxi avivpxi self-assigned this Aug 22, 2022
@avivpxi avivpxi linked a pull request Aug 23, 2022 that will close this issue
@avivpxi
Copy link
Collaborator Author

avivpxi commented Aug 23, 2022

@andeke07, this is resolved in v1.1.2
Showcased in this playground link.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants