Home > Backend Development > Golang > How to Unmarshal a Self-Referential JSON String in Go with a Dynamic Type?

How to Unmarshal a Self-Referential JSON String in Go with a Dynamic Type?

Mary-Kate Olsen
Release: 2024-12-25 13:13:09
Original
138 people have browsed it

How to Unmarshal a Self-Referential JSON String in Go with a Dynamic Type?

Unmarshalling JSON String to a Struct with a Self-Referential Element

In Go, unmarshalling a JSON string to a struct with a self-referential element can be challenging. Let's explore a specific example and a solution to address this issue effectively.

JSON Input and Struct Definition

Consider the following JSON input:

[{
    "db": {
        "url": "mongodb://localhost",
        "port": "27000",
        "uname": "",
        "pass": "",
        "authdb": "",
        "replicas": [
            {
                "rs01": {
                    "url":"mongodb://localhost",
                    "port": "27001",
                    "uname": "",
                    "pass": "",
                    "authdb": ""
                }
            },
            {
                "rs02": {
                    "url":"mongodb://localhost",
                    "port": "27002",
                    "uname": "",
                    "pass": "",
                    "authdb": ""
                }
            }
        ]
    }
}]
Copy after login

And the corresponding Go struct:

type DBS struct {
    URL      string   `json:"url"`
    Port     string   `json:"port"`
    Uname    string   `json:"uname"`
    Pass     string   `json:"pass"`
    Authdb   string   `json:"authdb"`
    Replicas []DBS     `json:"replicas"`
}
Copy after login

Unmarshal Function and Output

The provided function, loadConfigs(), attempts to unmarshal the JSON string into a slice of DBS structs:

func loadConfigs() []DBS {
    var config []DBS
    raw, err := ioutil.ReadFile("./config.json")
    if err != nil {
        fmt.Println(err.Error())
        os.Exit(1)
    }

    json.Unmarshal(raw, &config)
    return config
}
Copy after login

However, this results in an empty slice, []DBS{, because the JSON input is not a slice of DBS structs but a JSON object wrapper containing an array of objects.

Solution: Mapping to a Dynamic Type

To fully describe the JSON input, a dynamic type like a map is required. The updated type definition becomes:

type DBSReplicated struct {
    DB *DBS `json:"db"`
}
Copy after login
type DBS struct {
    URL      string            `json:"url"`
    Port     string            `json:"port"`
    Uname    string            `json:"uname"`
    Pass     string            `json:"pass"`
    Authdb   string            `json:"authdb"`
    Replicas []map[string]*DBS `json:"replicas"`
}
Copy after login

Using this new type, we can parse the JSON input accurately:

var dbs []*DBReplicated
if err := json.Unmarshal([]byte(src), &dbs); err != nil {
    panic(err)
}

db := dbs[0].DB
fmt.Printf("%+v\n", db)
for _, dbs := range db.Replicas {
    for name, replica := range dbs {
        fmt.Printf("%s: %+v\n", name, replica)
    }
}
Copy after login

Output

&{URL:mongodb://localhost Port:27000 Uname: Pass: Authdb: Replicas:[map[rs01:0x10538200] map[rs02:0x10538240]]}
rs01: &{URL:mongodb://localhost Port:27001 Uname: Pass: Authdb: Replicas:[]}
rs02: &{URL:mongodb://localhost Port:27002 Uname: Pass: Authdb: Replicas:[]}
Copy after login

Key Points

  • Use a map type to model dynamic JSON input.
  • Pay attention to the proper syntax for JSON tag property names.
  • Consider using pointers in the struct to allow for nested structs.

The above is the detailed content of How to Unmarshal a Self-Referential JSON String in Go with a Dynamic Type?. 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