Reputation:
I am working on a project in golang and I need to work with JSON response. The thing is that a value in JSON coming from server can be something like
{person: "john"}
or
{person: {name:"john"}}
so to create a structure for capturing this I have a couple of options:
1) make person type as interface{}, but this will have redundant code later to work with the value
2) store values in new properties, like PersonAsString and PersonAsObject, this makes code bit more unpredictable as it meant to be used as a module for other developers
any other pros and cons for this? any other suggestions how to treat unknown type JSON fields?
Upvotes: 1
Views: 658
Reputation: 192
Another option is to define a type with custom JSON marshal and unmarshal functions.
type Person string
func (p *Person) UnmarshalJSON(b []byte) error {
if strings.HasPrefix(string(*p),"{"){
value := map[string]string{}
json.Unmarshal(b,&value)
*p = Person(value["name"])
}else{
*p = Person(b)
}
return nil
}
func (p Person) MarshalJSON() ([]byte, error) {
return []byte(p),nil
}
type PersonStruct struct{
Person Person `json:"person"`
}
func main(){
one := `{"person": "john"}`
two := `{"person": {name:"john"}}`
result := PersonStruct{}
json.Unmarshal([]byte(one),&result)
fmt.Println(result)
json.Unmarshal([]byte(two),&result)
fmt.Println(result)
}
Upvotes: 3
Reputation: 17091
In this case you have to use interface{}
.
But with purpose to reduce complexity of your struct you can have one additional field like NameValue
and fill this value after json.Unmarshal
and assign value or from person
either from person.name
.
In your code you can loosely use NameValue
which will always contain correct value.
Upvotes: 0