0

I'm using the json.unmarshalling function in golang to decode some JSON responses we got from the API. How do I make it handle multiple types?

The response we receive are always status code and a message, but the json field have different names. Sometimes these two fields are called code and message and sometimes they are called statuscode and description, depending on what we query.

say that we queries Apple and this is simply solved by creating an Apple type struct like this:

type Apple struct {
    Code        int    `json:"code"`
    Description string `json:"message"`
}

But when we query Peach, the json we got back is no longer code and message anymore, the field names became statuscode and description. So we will need the following:

type Peach struct {
    Code        int    `json:"statuscode"`
    Description string `json:"description"`
}

Potentially, we need to set up 50 more types and write duplicate for 50 times?? There MUST be a better way to do this. Unfortunately I'm new to Golang and don't know how polymorphism works in this language. Please help.

guzmonne
  • 2,490
  • 1
  • 16
  • 22
StevenD
  • 21
  • 3
  • Show the function you woukd write for one of the types. – Charlie Tumahai Jul 15 '19 at 22:56
  • Please check [this stackoverflow](https://stackoverflow.com/questions/44380095/polymorphic-json-unmarshalling-of-embedded-structs) question for your answer. Look at the one given by @putu for a way to solve your issue. And please, use the search function before asking a question. – guzmonne Jul 15 '19 at 22:58
  • Just unmashal into a `map[string]interface{}` - will take any JSON type (Numbers are unmarshaled into `float64`) and you can get an item by it's name. Just remember to safely type assert the items. – hewiefreeman Jul 15 '19 at 23:02
  • A safe type assertion: `if value, ok := map["itemName"].(int); !ok { /* Item is an incorrect type - return an error */ }` – hewiefreeman Jul 15 '19 at 23:05
  • is this your own api or a 3rd party api? If it's your own api, can you not just make it always use the same structure for code/description? – user10753492 Jul 16 '19 at 01:38
  • Obviously, I fail to get the point. We _are_ talking of 50 distinct types, are we not? – Markus W Mahlberg Jul 16 '19 at 06:50
  • Are you looking for something like this: https://play.golang.org/p/sQpo3CBdKYe ? – Markus W Mahlberg Jul 16 '19 at 07:02
  • I found out the answer about this question. Thanks all for the help. – StevenD Jul 17 '19 at 20:46

1 Answers1

0

As far as I know , You should always decode into structs to benefit from go static types , the methods attached to that struct and perhaps be able to validate your responses with a package like validator , but you could always parse the JSON body into a map like this :

// JsonParse parses the json body of http request
func JsonParse(r *http.Request) (map[string]interface{}, error) {
    // Read the r.body into a byte array
    body, err := ioutil.ReadAll(r.Body)
    if err != nil {
        return nil, err
    }
    // Make a map of String keys and Interface Values
    b := make(map[string]interface{})
    // Unmarshal the body array into the map
    err = json.Unmarshal(body, &b)
    if err != nil {
        return nil, err
    }
    return b, nil
}