Unmarshalling JSON with Variable Array Return
When retrieving JSON from external sources, the structure of the response can vary, making it challenging to unmarshal into a fixed Go struct. This is particularly evident when the JSON may contain an array or a single object for the same property.
In the provided example, the JSON response contains a property called "gwrcmd" that can either be an array of objects or a singular object. To address this, one approach involves creating a second struct with the same fields as the original but with a slice for the "gwrcmd" property. However, a more flexible solution can be achieved using json.RawMessage.
json.RawMessage allows for the unmarshalling of unknown types into a raw JSON string. This feature can be used to peek into the JSON and determine the appropriate way to unmarshal it into the corresponding Go type.
Consider the following simplified example:
type Response struct { RawAWrapper struct { RawA json.RawMessage `json:"a"` } A A `json:"-"` As []A `json:"-"` } type A struct { B string } func (r *Response) UnmarshalJSON(b []byte) error { if err := json.Unmarshal(b, &r.RawAWrapper); err != nil { return err } if r.RawAWrapper.RawA[0] == '[' { return json.Unmarshal(r.RawAWrapper.RawA, &r.As) } return json.Unmarshal(r.RawAWrapper.RawA, &r.A) }
In this example, the json.RawMessage field RawA captures the JSON value of the "a" property. Based on the first byte of the raw JSON, we can determine whether the value is an array ([]) or an object ("{"). This information is then used to unmarshal the value into either the A struct (for objects) or the As slice (for arrays).
This approach provides a more flexible and robust way to handle JSON responses with variable structures. It eliminates the need for duplicate structs and allows for dynamic unmarshalling based on the JSON content.
The above is the detailed content of How to Handle Variable Array Returns When Unmarshalling JSON in Go?. For more information, please follow other related articles on the PHP Chinese website!