Home >Backend Development >Golang >How Can I Successfully Unmarshal Nested JSON with Dynamic Keys in Go?

How Can I Successfully Unmarshal Nested JSON with Dynamic Keys in Go?

Barbara Streisand
Barbara StreisandOriginal
2024-12-18 09:42:22417browse

How Can I Successfully Unmarshal Nested JSON with Dynamic Keys in Go?

Unmarshalling JSON with Recursive Structures

Consider the following JSON string representing a configuration for MongoDB:

[{
    "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": ""
                }
            }
        ]
    }
}]

We have a struct, DBS, that models the JSON:

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`
}

However, we encounter an issue when unmarshalling the JSON using json.Unmarshal. After the process, our DBS slice remains empty.

The underlying problem is that our JSON input has an additional JSON object wrapping our DBS values, and our DBS values are properties of the "db" object. Additionally, the "replicas" array contains objects with varying keys that can be represented by DBS.

To accurately model this JSON, we need a "dynamic" type. A map serves as a suitable option. Therefore, the appropriate structure for our JSON is []map[string]DBS.

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"`
}

This alternative structure effectively parses the JSON input:

// ...

if err := json.Unmarshal([]byte(src), &dbs); err != nil {
    panic(err)
}
fmt.Printf("%+v", dbs)

The output represents the JSON structure accurately.

Furthermore, we can optimize the model by using pointers and modeling the first level, which is always "db":

type DBReplicated struct {
    DB *DBS `json:"db"`
}

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"`
}

This updated model provides a more concise and efficient representation of the JSON configuration.

The above is the detailed content of How Can I Successfully Unmarshal Nested JSON with Dynamic Keys in Go?. 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