处理两种形式的JSON?

I'm writing an application in Go that will recieve two forms of JSON:

Example 1:

{"book_data":{"title":"book-title","page_number":457}}

Example 2:

{"book_data":{"collection":214},"books":{"data":[{"title":"book-title","page_number":457},{"title":"book-title","page_number":354}]}}

I thought that I could create a struct like the following and unmarshal JSON into it:

type Book struct {
    Title      string `json:"title"`
    PageNumber int    `json:"page_number"`
}

but that only works for the first example.

How can I handle JSON from both examples?

You can first unmarshal partly in json.RawMessage to next decide depending of unmarshalled payload. And you also can just unmarshal in more generic structure. Something like

type Book struct {
    Title      string `json:"title"`
    PageNumber int    `json:"page_number"`
}
type BookShelf struct {
    BookData struct {
        Book
        Collection int `json:"collection"`
    } `json:"book_data"`
    Books struct {
        Data []Book `json:"data"`
    } `json:"books"`
}

which for me looks readable, meaningful and handy enough for further processing.

Why not unmarshal to a map[string]interface{} and then use the result to see which form you need to handle? You can then deserialize with a specific struct type for each form.

Another way would be to use the following package to check for differing attributes, so you can decide which struct to use for the real unmarshaling.

https://github.com/go-xmlpath/xmlpath/tree/v2

You can unmarshal to map because your key is string and value may be anything like - map[string]interface{}. If you are not sure any data type or value then use interface{} beacause it can store any value. Then use result to see which form it is, And deserialize to specific struct type.

Another way to convert JSON to go struct is use this tool. https://mholt.github.io/json-to-go/