Assume a JSON object with the general format
"accounts": [
{
"id": "<ACCOUNT>",
"tags": []
}
]
}
I can create a struct with corresponding json tags to decode it like so
type AccountProperties struct {
ID AccountID `json:"id"`
MT4AccountID int `json:"mt4AccountID,omitempty"`
Tags []string `json:"tags"`
}
type Accounts struct {
Accounts []AccountProperties `json:"accounts"`
}
But the last struct with just one element seems incorrect to me. Is there a way I could simply say type Accounts []AccountProperties `json:"accounts"`
instead of creating an entire new struct just to decode this object?
You need somewhere to store the json string accounts
. Using a:
var m map[string][]AccountProperties
suffices, though of course you then need to know to use the string literal accounts
to access the (single) map entry thus created:
type AccountProperties struct {
ID string `json:"id"`
MT4AccountID int `json:"mt4AccountID,omitempty"`
Tags []string `json:"tags"`
}
func main() {
var m map[string][]AccountProperties
err := json.Unmarshal([]byte(data), &m)
fmt.Println(err, m["accounts"])
}
See complete Go Playground example (I had to change the type of ID
to string
and fix the missing {
in the json).
As Dave C points out in comments, this is no shorter than just using an anonymous struct type:
var a struct{ Accounts []AccountProperties }
in terms of the Unmarshall
call (and when done this way it's more convenient to use). Should you want to use an anonymous struct like this in a json.Marshall
call, you'll need to tag its single element to get a lowercase encoding: without a tag it will be called "Accounts"
rather than "accounts"
.
(I don't claim the map method to be better, just an alternative.)