Как насчет такого варианта?
https://play.golang.org/p/kqqWgqNacZO
package main
import (
"encoding/json"
"fmt"
)
type TemplateCategory struct {
ID int `json:"id"`
Name string `json:"name"`
}
type Template struct {
Name string `json:"name"`
CategoryInfoRaw *json.RawMessage `json:"category_info"`
CategoryInfo *TemplateCategory
}
func (t *Template) UnmarshalJSON(data []byte) error {
type template Template
if err := json.Unmarshal(data, (*template)(t)); err != nil {
return err
}
if t.CategoryInfoRaw == nil || string(*t.CategoryInfoRaw) == "[]" {
t.CategoryInfo = nil
} else {
if err := json.Unmarshal(*t.CategoryInfoRaw, &t.CategoryInfo); err != nil {
return err
}
}
return nil
}
func main() {
res := &Template{}
str1 := `{
"name": "Мой шаблон",
"category_info": {
"id": 109,
"name": "Тест"
}
}`
str2 := `{
"name": "Мой шаблон",
"category_info": []
}`
_ = json.Unmarshal([]byte(str1), res)
fmt.Printf("%+v\n", res)
fmt.Printf("%+v\n", res.CategoryInfo)
_ = json.Unmarshal([]byte(str2), res)
fmt.Printf("%+v", res)
}
Прошу прощение за форматирование - под рукой был только go-playground