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!