Flattening Marshalled JSON Structs with Anonymous Members in Go
The provided code attempts to transform structs containing anonymous members into flattened JSON objects with custom "_links" fields. However, the anonymous member "Anything" is being treated as a named field, leading to undesired JSON structures.
Understanding Anonymous Member Handling in JSON Marshaling
Go's JSON marshaler treats anonymous struct fields as if their inner exported fields were fields in the outer struct. This behavior can be overridden by providing a JSON tag with a name, but there is no explicit mechanism for flattening anonymous members.
Solution Using Reflection
To achieve the desired flattening, the below solution utilizes the reflect package. By iterating over the fields of the struct, we can create a map[string]interface{} that retains the structure of the original object without introducing new fields:
<code class="go">func MarshalHateoas(subject interface{}) ([]byte, error) { links := make(map[string]string) out := make(map[string]interface{}) subjectValue := reflect.Indirect(reflect.ValueOf(subject)) subjectType := subjectValue.Type() for i := 0; i < subjectType.NumField(); i++ { field := subjectType.Field(i) name := subjectType.Field(i).Name out[field.Tag.Get("json")] = subjectValue.FieldByName(name).Interface() } ... }</code>
Example Usage
The following example demonstrates the flattened JSON output for a User and Session struct:
<code class="go">package main import ( "encoding/json" "fmt" "reflect" ) type User struct { Id int `json:"id"` Name string `json:"name"` } type Session struct { Id int `json:"id"` UserId int `json:"userId"` } func MarshalHateoas(subject interface{}) ([]byte, error) { ... } func main() { u := &User{123, "James Dean"} s := &Session{456, 123} json, err := MarshalHateoas(u) if err != nil { panic(err) } else { fmt.Println("User JSON:") fmt.Println(string(json)) } json, err = MarshalHateoas(s) if err != nil { panic(err) } else { fmt.Println("Session JSON:") fmt.Println(string(json)) } }</code>
JSON Output:
User JSON: { "id": 123, "name": "James Dean", "_links": { "self": "http://user/123" } } Session JSON: { "id": 456, "userId": 123, "_links": { "self": "http://session/456" } }
The above is the detailed content of How Can I Flatten JSON Structs with Anonymous Members in Go?. For more information, please follow other related articles on the PHP Chinese website!