1

Say I want to be able to handle both nested and unnested jsons of the following form, as in this example:

source_json_1 := `{"owner": "John", "nickname": "Rose", "species": "Dog"}`
source_json_2 := `{"owner": "Doe", "Pet": [{"nickname": "Rose", "species": "Dog"},
                                          {"nickname": "Max", "species": "Cat"}]}`

If I define Pet as an embedded struct I can easily unmarshal it with:

type Owner struct {
    Name string
    Pet
}

type Pet struct {
    NickName    string
    Species     string
}

Resulting in John's pet getting adequately marshalled.

{John {Rose Dog}}
{Doe { }}

But since Pet can actually also be a slice of Pets, Doe's Pets are not correctly unmarshalled. If instead go with

type Owner struct {
    Name string
    Pet  []Pet
}

Then Doe gets marshalled just fine.

{John []}
{Doe [{Rose Dog} {Max Cat}]}

How can I catch both cases?

I'd prefer to marshall it into a slice of Pets in the end, no matter what.

1
  • 1
    Pet is embedded, but it is not anonymous - it's named Pet. Commented Jun 16, 2017 at 16:50

1 Answer 1

2

You're looking at two separate data structures, so to unmarshal them with a single struct type, you'd need to account for both:

type Owner struct {
    Name string
    Pet
    Pets []Pet `json:"Pet"`
}

Then, if you want the slice to be authoritative, after you unmarshall, move the embedded to the slice:

// owner := unmarshall blah blah
if owner.Pet != Pet{} {
    owner.Pets = append(owner.Pets, owner.Pet)
}
Sign up to request clarification or add additional context in comments.

3 Comments

Ideally, if you can control the program generating the JSON, just use the array annotation exclusively. If the owner only has one pet, then the array only has a single entry, but it's still an array. No reason to have two separate structures to convey the same information when they are not actually logically distinct situations.
Agreed. My assumption was that the incoming data was outside their control.
Agree fully, I was looking for a more general pattern to handle denormalized data that needs to be normalized before it goes into a database. The above pattern is elegant

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.