Home  >  Article  >  Backend Development  >  How to flatten Marshalled JSON Structs in Go with anonymous members?

How to flatten Marshalled JSON Structs in Go with anonymous members?

Susan Sarandon
Susan SarandonOriginal
2024-11-02 18:21:30414browse

How to flatten Marshalled JSON Structs in Go with anonymous members?

Flattening Marshalled JSON Structs with Anonymous Members in Go

In the following code:

<code class="go">type Anything interface{}

type Hateoas struct {
    Anything
    Links map[string]string `json:"_links"`
}

func MarshalHateoas(subject interface{}) ([]byte, error) {
    h := &Hateoas{subject, make(map[string]string)}
    switch s := subject.(type) {
    case *User:
        h.Links["self"] = fmt.Sprintf("http://user/%d", s.Id)
    case *Session:
        h.Links["self"] = fmt.Sprintf("http://session/%d", s.Id)
    }
    return json.MarshalIndent(h, "", "    ")
}</code>

the goal is to marshal JSON in a way where the anonymous member is flattened. By default, the anonymous member is treated as a separate named field in the JSON output.

The solution to this is to use the reflect package to manually map the fields of the struct we wish to serialize to a map[string]interface{}. In this way, we can retain the flat structure of the original struct without introducing new fields.

Here's the code that accomplishes this:

<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()
    }
    switch s := subject.(type) {
    case *User:
        links["self"] = fmt.Sprintf("http://user/%d", s.Id)
    case *Session:
        links["self"] = fmt.Sprintf("http://session/%d", s.Id)
    }
    out["_links"] = links
    return json.MarshalIndent(out, "", "    ")
}</code>

This code iterates over the fields of the struct, retrieves their values, and adds them to the output map using the field's JSON tag as the key. This process ensures that the anonymous member's fields are flattened into the output map.

By customizing the JSON marshaling process in this way, we can achieve the desired JSON output while maintaining the flexibility and type safety provided by an interface.

The above is the detailed content of How to flatten Marshalled JSON Structs in Go with anonymous members?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn