Home > Backend Development > Golang > How Can I Flatten JSON Structs with Anonymous Members in Go?

How Can I Flatten JSON Structs with Anonymous Members in Go?

Mary-Kate Olsen
Release: 2024-10-28 05:20:30
Original
324 people have browsed it

How Can I Flatten JSON Structs with Anonymous Members in Go?

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>
Copy after login

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>
Copy after login

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"
    }
}
Copy after login

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!

source:php.cn
Statement of this Website
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
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template