5

I am working with an API that, frustratingly, has field names that vary for the same value. For example, one API response could look like this:

{
  "PersonFirstName": "John",
  "PersonLastName": "Smith"
}

while another looks like this:

{
  "FirstNm": "John",
  "LastNm": "Smith"
}

Suppose then I had a struct which I would like to decode my JSON to. It might look like this:

type Name struct {
    FirstName string
    LastName  string
}

Typically I would just be able to do the following if the API was consistent:

type Name struct {
    FirstName string `json:"PersonFirstName"`
    LastName  string `json:"PersonLastName"`
}

and then use the built-in JSON decoder to build the struct. When there are multiple field values like this, though, I don't know a clean way to decode the JSON into a struct. Any ideas?

eric
  • 51
  • 1
  • 3

1 Answers1

1

Use a map[string]string. That is the equivalent structure in Go. You're looking at those as being structs because their objects, and that's the sensible thing to do. Anytime you see different values for the property names that's your clue that a map is the only reasonable representation of the data in Go.

If you need to normalize/have static typing implement a helper function called NameFromMap(data map[string]string) (*Name, error). Put the switch statement in there to deal with the various values you can have for the keys.

Edit: you could also implement UnmarshalJSON for your type. You would just put this switch statement I allude to there. Here's an example; How do I Unmarshal JSON?

I personally prefer the first method I said because this sort of abstracts a step that I'd rather see called explicitly.

Community
  • 1
  • 1
evanmcdonnal
  • 46,131
  • 16
  • 104
  • 115
  • That would be sensible, but this was just an example API response that was simplified. This approach wouldn't handle having nested objects, arrays, or numbers in the response. – eric Jun 25 '15 at 22:56
  • @eric the option I linked to might better suit your needs then. The approach I mention could still work, it's just anywhere where the property names could change you need a `map[string]TheType`. Keep in mind you could have maps within maps or an object that is mainly static and has a couple of maps inside it for these particular properties that change. – evanmcdonnal Jun 25 '15 at 23:00