Golang json.Unmarshal is not working as expected - json

Im trying to unmarshal json response from vcenter rest api. when the response body is simply printed it looks like the o/p below
{"value":[{"memory_size_MiB":16384,"vm":"vm-10236","name":"Normal_Windows_192.168.1.10","power_state":"POWERED_OFF","cpu_count":8},{"memory_size_MiB":8192,"vm":"vm-10238","name":"Normal_Windows_192.168.1.11","power_state":"POWERED_OFF","cpu_count":4}]}
i have exported both struct and struct fields however the fields like memory_size_MiB, power_state,cpu_count is not being unmarshalled. when the struct is printed it looks like below:-
{Value:[{Mem:0 Vm:vm-10236 Name:Normal_Windows_192.168.1.10 Powerstat: Cpu:0} {Mem:0 Vm:vm-10238 Name:Normal_Windows_192.168.1.11 Powerstat: Cpu:0} {Mem:0 Vm:vm-10582 Name:Normal_Windows_192.168.1.12 Powerstat: Cpu:0}]}%
Below is my main.go
package main
import (
...
)
type SessionData struct {
VmwareApiSessionId string `json:"value"`
}
//{"memory_size_MiB":16384,"vm":"vm-10236","name":"Normal_Windows_192.168.19.100","power_state":"POWERED_OFF","cpu_count":8}
type Vm struct {
Mem int `json: "memory_size_MiB"`
Vm string `json: "vm"`
Name string `json: "name"`
Powerstat string `json: "power_state"`
Cpu int `json: "cpu_count"`
}
//{Value:[{Mem:0 Vm:vm-10236 Name:Normal_Windows_192.168.1.10 Powerstat: Cpu:0} {Mem:0 Vm:vm-10238 Name:Normal_Windows_192.168.1.11 Powerstat: Cpu:0} {Mem:0 Vm:vm-10582 Name:Normal_Windows_192.168.1.12 Powerstat: Cpu:0}]}
type ColVmList struct {
Value []Vm `json: "value"`
}
func getVmList(sessid string,cli *http.Client) ColVmList {
vms := ColVmList{}
req,err:=http.NewRequest("GET","https://sandbox.vmware.local/rest/vcenter/vm",nil)
req.Header.Add("vmware-api-session-id",sessid)
resp,err := cli.Do(req)
if err != nil {
log.Fatal("Error %s", err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
err = json.Unmarshal([]byte(body),&vms)
if err != nil {
log.Fatal("error %s", err)
}
return vms
}
func main(){
//authpart
loginurl = "https://sandbox.vmware.local/rest/com/vmware/cis/session"
//login...
err = json.Unmarshal([]byte(string(body)),&sessVal)
if err != nil{
log.Fatal(err)
}
var allvmlist ColVmList
allvmlist = getVmList(sessVal.VmwareApiSessionId,&cli)
fmt.Printf("%v",allvmlist)
}

Your struct tags are not well formed. Remove the space between json: and the string "..." in the struct tags. i.e. it MUST be json:"..." not json: "...".
And the reason some fields are correctly unmarshaled even with not well-formed struct tags is because the fields' names match the json property names.
func main() {
data := []byte(`{"memory_size_MiB":16384}`)
var obj1 struct {
Mem int `json: "memory_size_MiB"`
}
if err := json.Unmarshal(data, &obj1); err != nil {
panic(err)
}
fmt.Println(obj1)
var obj2 struct {
Mem int `json:"memory_size_MiB"`
}
if err := json.Unmarshal(data, &obj2); err != nil {
panic(err)
}
fmt.Println(obj2)
}
https://go.dev/play/p/gUR5ed2n0D1

Related

Parse stringified JSON

I'm trying to parse stringified JSON with Go, but I cannot find anything that explains how do to efficient parsing.
Example JSON:
{
"messages":"<ul class=\"messages\"><li class=\"success-msg\"><ul><li><span>Item succcessfully added<\/span><\/li><\/ul><\/li><\/ul>",
"app_cart":"[]",
"addcartrows":"[{\"productId\":\"1675688\",\"quantity\":1,\"unitPrice\":\"290.00\",\"currency\":\"EUR\",\"sku\":\"P00525485-3\"}]",
"minicart_content":"<ul class=\"checkout-types minicart\">\n
<li>",
"cart_qty":"1",
"added_product_json":"{\"id\":\"1675695\",\"size\":\"40\"}"
}
I usually parse json by casting it to a struct. like this:
type AutoGenerated struct {
Messages string `json:"messages"`
AppCart string `json:"app_cart"`
Addcartrows string `json:"addcartrows"`
MinicartContent string `json:"minicart_content"`
CartQty string `json:"cart_qty"`
AddedProductJSON string `json:"added_product_json"`
}
var j AutoGenerated
if err = json.Unmarshal(body, &AutoGenerated); err != nil {
fmt.Println(err) // json: cannot unmarshal string into Go struct field AutoGenerated.added_product_json
}
However I do not know how to correctly parse this type of response.
Any help?
do it in two steps.
package main
import (
"encoding/json"
"fmt"
)
func main() {
type AutoGenerated struct {
Messages string `json:"messages"`
AppCart string `json:"app_cart"`
Addcartrows string `json:"addcartrows"`
MinicartContent string `json:"minicart_content"`
CartQty string `json:"cart_qty"`
AddedProductJSON string `json:"added_product_json"`
}
type addedProduct struct {
ID string `json:"id"`
Size string `json:"size"`
}
type productRow struct {
ProductID string `json:"productId"`
Quantity int `json:"quantity"`
UnitPrice string `json:"unitPrice"`
Currency string `json:"currency"`
SKU string `json:"sku"`
}
var j AutoGenerated
body := []byte(`{
"messages":"<ul class=\"messages\"><li class=\"success-msg\"><ul><li><span>Item succcessfully added<\/span><\/li><\/ul><\/li><\/ul>",
"app_cart":"[]",
"addcartrows":"[{\"productId\":\"1675688\",\"quantity\":1,\"unitPrice\":\"290.00\",\"currency\":\"EUR\",\"sku\":\"P00525485-3\"}]",
"minicart_content":"<ul class=\"checkout-types minicart\">\n<li>",
"cart_qty":"1",
"added_product_json":"{\"id\":\"1675695\",\"size\":\"40\"}"
}`)
if err := json.Unmarshal(body, &j); err != nil {
panic(err)
}
var k []productRow
if err := json.Unmarshal([]byte(j.Addcartrows), &k); err != nil {
panic(err)
}
var u addedProduct
if err := json.Unmarshal([]byte(j.AddedProductJSON), &u); err != nil {
panic(err)
}
fmt.Printf("%#v\n\n", j)
fmt.Printf("%#v\n\n", k)
fmt.Printf("%#v\n\n", u)
}
Assuming the json you have added has a formatting issue for value of "minicart_content" , below should help -
package main
import (
"fmt"
"encoding/json"
)
var myjson string = `{
"messages": "<ul class=\"messages\"><li class=\"success-msg\"><ul><li><span>Item succcessfully added<\/span><\/li><\/ul><\/li><\/ul>",
"app_cart": "[]",
"addcartrows": "[{\"productId\":\"1675688\",\"quantity\":1,\"unitPrice\":\"290.00\",\"currency\":\"EUR\",\"sku\":\"P00525485-3\"}]",
"minicart_content": "<ul class=\"checkout-types minicart\">\n <li > ",
"cart_qty": "1",
"added_product_json": "{\"id\":\"1675695\",\"size\":\"40\"}"
}`
type AutoGenerated struct {
Messages string `json:"messages"`
AppCart string `json:"app_cart"`
Addcartrows string `json:"addcartrows"`
MinicartContent string `json:"minicart_content"`
CartQty string `json:"cart_qty"`
AddedProductJSON string `json:"added_product_json"`
}
func main() {
var j AutoGenerated
if err := json.Unmarshal([]byte(myjson), &j); err != nil {
fmt.Println(err)
}
fmt.Println(j.AddedProductJSON)
}

Unable to unmarshal golang response

I've been trying to extract some JSON by unmarshalling my json response into structs, but I have no idea why it's not doing it properly. I've also tried gjson but same result. Am I missing something here?
JSON Result:
{"availabilities":[{"pickup":{"status":"OnlineOnly","purchasable":false},"shipping":{"status":"InStockOnlineOnly","purchasable":true},"sku":"12341231","sellerId":"438178","saleChannelExclusivity":"OnlineOnly","scheduledDelivery":false,"isGiftCard":false,"isService":false}]}
Code:
// Inventory ...
type Inventory struct {
Availabilities []Availability `json:"availabilities"`
}
// Availability ...
type Availability struct {
Sku string `json:"sku"`
SellerID string `json:"sellerId"`
SaleChannelExclusivity string `json:"saleChannelExclusivity"`
ScheduledDelivery bool `json:"scheduledDelivery"`
IsGiftCard bool `json:"isGiftCard"`
IsService bool `json:"isService"`
Pickup Statuses `json:"pickup"`
Shipping Statuses `json:"shipping"`
}
// Statuses ..
type Statuses struct {
Status string `json:"status"`
Purchasable bool `json:"purchasable"`
}
func (pr *Program) checkInventory() {
url := fmt.Sprintf("https://www.bestbuy.ca/ecomm-api/availability/products?accept-language=en-CA&skus=%s", pr.Sku)
log.Infof("URL %s", url)
resp, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
log.Info(string(bodyBytes))
var inv Inventory
json.Unmarshal(bodyBytes, &inv)
log.Infof("%+v", inv)
}
Console:
INFO[2020-04-07T03:01:10-07:00] URL https://www.bestbuy.ca/ecomm-api/availability/products?accept-language=en-CA&skus=12341231
INFO[2020-04-07T03:01:10-07:00] {"availabilities":[{"pickup":{"status":"OnlineOnly","purchasable":false},"shipping":{"status":"InStockOnlineOnly","purchasable":true},"sku":"12341231
,"sellerId":"438178","saleChannelExclusivity":"OnlineOnly","scheduledDelivery":false,"isGiftCard":false,"isService":false}]}
INFO[2020-04-07T03:01:10-07:00] {Availabilities:[]}
The problem is in the json.Unmarshall call. It is returning an error: "invalid character 'ï' looking for beginning of value” from json.Unmarshal
As it is explained here: The server is sending you a UTF-8 text string with a Byte Order Mark (BOM). The BOM identifies that the text is UTF-8 encoded, but it should be removed before decoding.
This can be done with the following line (using package "bytes"):
body = bytes.TrimPrefix(body, []byte("\xef\xbb\xbf"))
So the resulting working code is:
// Inventory ...
type Inventory struct {
Availabilities []Availability `json:"availabilities"`
}
// Availability ...
type Availability struct {
Sku string `json:"sku"`
SellerID string `json:"sellerId"`
SaleChannelExclusivity string `json:"saleChannelExclusivity"`
ScheduledDelivery bool `json:"scheduledDelivery"`
IsGiftCard bool `json:"isGiftCard"`
IsService bool `json:"isService"`
Pickup Statuses `json:"pickup"`
Shipping Statuses `json:"shipping"`
}
// Statuses ..
type Statuses struct {
Status string `json:"status"`
Purchasable bool `json:"purchasable"`
}
func (pr *Program) checkInventory() {
url := fmt.Sprintf("https://www.bestbuy.ca/ecomm-api/availability/products?accept-language=en-CA&skus=%s", pr.Sku)
log.Infof("URL %s", url)
resp, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
body := bytes.TrimPrefix(bodyBytes, []byte("\xef\xbb\xbf"))
log.Info(string(body))
var inv Inventory
err = json.Unmarshal([]byte(body), &inv)
if err != nil {
log.Fatal(err)
}
log.Infof("%+v", inv)
}

How to pass struct as a parameter to a function

How can I do something Like this?
I am trying to pass a struct as a parameter to function in Go.
func handleEntityProperties(w http.ResponseWriter, r *http.Request) {
const sliceSize = 100
var entityProperties struct {
Instance string `json:"instance"`
Entities []struct {
Id string `json:"id"`
Properties map[string]string `json:"properties"`
Type string `json:"type"`
} `json:"entities"`
}
body, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
if !json.Valid([]byte(body)) {
fmt.Fprintf(w, "invalid json")
return
}
err = json.Unmarshal(body, &entityProperties)
sendData(entityProperties.Entities[0:100])
return
}
func sendData(entities struct) {
log.Println("Doing things with entities ", entities)
}
as you can see in code I am trying to send first 100 elements of entityProperties.Entities struct to a sendData. I know this is syntactically wrong.
Just declare your type outside of the functions:
type entity struct {
Id string `json:"id"`
Properties map[string]string `json:"properties"`
Type string `json:"type"`
}
And reuse it in handleEntityProperties() and in the signature of sendData():
func handleEntityProperties(w http.ResponseWriter, r *http.Request) {
const sliceSize = 100
var entityProperties struct {
Instance string `json:"instance"`
Entities []entity `json:"entities"`
}
body, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
if !json.Valid([]byte(body)) {
fmt.Fprintf(w, "invalid json")
return
}
err = json.Unmarshal(body, &entityProperties)
sendData(entityProperties.Entities[0:sliceSize])
return
}
func sendData(entities []entity) {
log.Println("Doing things with entities ", entities)
}
Also note that there is no guarantee that the client will send at least 100 entities, so you should check that else the slicing expression might result in a runtime panic:
max := 100
if len(entityProperties.Entities) < max {
max = len(entityProperties.Entities)
}
sendData(entityProperties.Entities[:max])
Also that check for invalid JSON is unnecessary: if the JSON is invalid, json.Unmarshal() will report a (non-nil) error and you'll know it.
Going further, you don't even have to read the complete body into memory (into a byte slice), you may use json.Decoder to read from it directly (without the intermediate memory buffer) like this:
dec := json.NewDecoder(r.Body)
if err := dec.Decode(&entityProperties); err != nil {
// handle error
}
And the final return statement is also unnecessary.
So an improved version may look like this:
func handleEntityProperties(w http.ResponseWriter, r *http.Request) {
var entityProperties struct {
Instance string `json:"instance"`
Entities []entity `json:"entities"`
}
dec := json.NewDecoder(r.Body)
if err := dec.Decode(&entityProperties); err != nil {
// handle error
http.Error(w, "invalid json", http.StatusBadRequest)
return
}
max := 100
if len(entityProperties.Entities) < max {
max = len(entityProperties.Entities)
}
sendData(entityProperties.Entities[:max])
}

How to prevent an array from being embedded into another array in my json response

In my api server I return a json object which has string arrays in it. I am finding that my arrays are being embedded into another array like this:
"Items": [
"[\"QQTISGXSJIS4DEV36JCBWQ4X\", \"HCOWEB7NVIQEUAINMM2KUV6J\", \"FCKP7D3H6Q7RQIRKSPVZBRHL\", \"UQLVH65PPBTVK6KMIV5KMGY6\", \"UR2XTXJFVURE5ERBLNW7ZUCR\", \"75N66F4DYGPM57V47N3IBMKD\", \"HQ2CRXQFPQM7TNNDZXZ2MQ2B\", \"3SLGKFR5GPHVZMQM4YM6KI4U\", \"UCQ3J7GYAYPZOCQKWIRGNGNY\", \"6INWDYWUFX6L5JYX2HEVMMHX\", \"ASQBRMKYSK2TINHBYQIWATS5\", \"QPCHVJ4HXYTUJNEZWQCKM5I3\", \"7JPYYH64Y3FQK6YJX5NBXMM6\", \"BI4NIBBOFBYAAS7ZROD6XEMB\", \"RGU3X36VYMXX4N3XPEZKY76K\", \"PLHVIQ7QT6TBWI5BZX6EJI74\", \"YATHGR6W6BIKFYXVZMGVBRB4\", \"ZZ5KZ5ZSBVLQRDKR2SJQ5CXW\", \"TNH56AOIMFSLOX5AW5I6WYP2\", \"VIFSURNJWJ6YYKXIWTWRNY6F\"]"
]
You can a complete JSON object here: https://gist.github.com/yshuman1/31b39333e2cd187707d98817171c3914
I am using gorm and saving my array as pq.StringArray.
Here is my function that returns that json:
func (u *Users) RetrieveItemCatModSort(w http.ResponseWriter, r *http.Request) {
var l model.ItemCatModSort
type data struct {
Email string
Password string
Location string
}
var form data
if err := parseForm(r, &form); err != nil {
log.Infof("error parsing form for logging in Kiosk %v", err)
return
}
user, err := u.us.ByEmail(string(form.Email))
if err != nil {
log.Infof("error looking up user by email while retrieving items %v", err)
return
}
bcrypt.CompareHashAndPassword([]byte(user.KioskPwHash), []byte(form.Password))
if err != nil {
log.Infof("invalid login credentials error: %v submitted data:\n%#v", err, form)
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(422) // unprocessable entity
if err := json.NewEncoder(w).Encode(err); err != nil {
panic(err)
}
}
//lookup oauth token in DB
token, err := u.os.Find(user.ID, "square")
if err != nil {
fmt.Println(err)
}
l.LocationID = form.Location
l.Modifiers, err = pos.GetModifiers(token.AccessToken, l.LocationID)
if err != nil {
log.Infof("Error grabbing modifiers using GetInventory. %#v", err)
}
l.Categories, err = pos.GetCategories(token.AccessToken)
if err != nil {
log.Infof("Error grabbing categories using GetInventory. %#v", err)
}
l.Items, err = pos.GetItems(token.AccessToken, l.LocationID)
if err != nil {
log.Infof("Error grabbing items using GetInventory. %#v", err)
}
l.ItemSort, err = u.is.FindItemSortByLocation(l.LocationID)
if err != nil {
log.Infof("Error grabbing item sort. %#v", err)
}
l.CatSort, err = u.is.FindCatSortByLocation(l.LocationID)
if err != nil {
log.Infof("Error grabbing cat sort. %#v", err)
}
lJSON, err := json.Marshal(l)
if err != nil {
log.Infof("error marshalling data to lJSON inside RetrieveLocationInv %v", err)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write(lJSON)
}
Here are some of the models that I use:
type Categories struct {
Categories []Category `json:"objects"`
}
type ItemCatModSort struct {
LocationID string
Categories Categories
Items []Item
Modifiers []Modifier
ItemSort []ItemSort
CatSort CatSort
}
type CatSort struct {
gorm.Model
LocationID string
Category pq.StringArray `gorm:"type:varchar(10485760)[]"`
}
type Item struct {
gorm.Model
Type string `json:"type"`
ID string `json:"id"`
UpdatedAt time.Time `json:"updated_at"`
Version int64 `json:"version"`
IsDeleted bool `json:"is_deleted"`
PresentAtAllLocations bool `json:"present_at_all_locations"`
PresentAtLocationIds []string `json:"present_at_location_ids"`
AbsentAtLocationIds []string `json:"absent_at_location_ids"`
ItemData struct {
Name string `json:"name"`
Description string `json:"description"`
Visibility string `json:"visibility"`
CategoryID string `json:"category_id"`
ModifierListInfo []struct {
ModifierListID string `json:"modifier_list_id"`
Visibility string `json:"visibility"`
MinSelectedModifiers int `json:"min_selected_modifiers"`
MaxSelectedModifiers int `json:"max_selected_modifiers"`
Enabled bool `json:"enabled"`
} `json:"modifier_list_info"`
ImageURL string `json:"image_url"`
Variations []struct {
Type string `json:"type"`
ID string `json:"id"`
UpdatedAt time.Time `json:"updated_at"`
Version int64 `json:"version"`
IsDeleted bool `json:"is_deleted"`
PresentAtAllLocations bool `json:"present_at_all_locations"`
PresentAtLocationIds []string `json:"present_at_location_ids"`
AbsentAtLocationIds []string `json:"absent_at_location_ids"`
ItemVariationData struct {
ItemID string `json:"item_id"`
Name string `json:"name"`
Sku string `json:"sku"`
Ordinal int `json:"ordinal"`
PricingType string `json:"pricing_type"`
PriceMoney struct {
Amount int `json:"amount"`
Currency string `json:"currency"`
} `json:"price_money"`
} `json:"item_variation_data"`
} `json:"variations"`
ProductType string `json:"product_type"`
SkipModifierScreen bool `json:"skip_modifier_screen"`
} `json:"item_data"`
}
basically instead of
"Items": [
"[\"QQTISGXSJIS4DEV36JCBWQ4X\", \"HCOWEB7NVIQEUAINMM2KUV6J\",... \"VIFSURNJWJ6YYKXIWTWRNY6F\"]" ]
looking like that, I'd want it to look like this:
"Items": ["QQTISGXSJIS4DEV36JCBWQ4X\", \"HCOWEB7NVIQEUAINMM2KUV6J\",... \"VIFSURNJWJ6YYKXIWTWRNY6F\" ]

go "encoding/json" : marshal json field

I have a PostgreSQL schema with json field's (DisplayInfo, and FormatInfo). Structure of this field's is dynamic.
I'can read and render it only as string (string type in render struct) :
[
{
"ID":9,
"Name":"120 №1",
"DisplayInfo":"{\"path\": \"http://path/to/img.png\"}",
"Format":{
"Code":"frame-120",
"Width":120,
"Height":60,
"FormatInfo":"[{\"name\": \"\\u0413\\u043b\\u0430\\u0432\\u043d\\u043e\\u0435 \\u0438\\u0437\\u043e\\u0431\\u0440\\u0430\\u0436\\u0435\\u043d\\u0438\\u0435\", \"field_type\": \"img\", \"key\": \"path\"}]"
},
"Weight":0.075,
"Application":8,
"Url":"//path/to/game",
"Referrer":""
}
]
but i want output field DisplayInfo as JSON object. How ?
My render code:
func renderJSON(w http.ResponseWriter, obj models.Model) {
js, err := json.Marshal(obj)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Write(js)
}
UPD 1 : Structure of this field's is dynamic. DisplayInfo may have 'path' field, or may not. They may have additional fields.
UPD 2. I wana output DisplayInfo and FormatInfo as json-object(not string), as part of whole object, like this:
[
{
"ID":9,
"Name":"120 №1",
"DisplayInfo":{"path": "http://path/to/img.png"},
"Format":{
"Code":"frame-120",
"Width":120,
"Height":60,
"FormatInfo":[{"name": "\\u0413\\u043b\\u0430\\u0432\\u043d\\u043e\\u0435 \\u0438\\u0437\\u043e\\u0431\\u0440\\u0430\\u0436\\u0435\\u043d\\u0438\\u0435", "field_type": "img", "key": "path"}]
},
"Weight":0.075,
"Application":8,
"Url":"//path/to/game",
"Referrer":""
}
]
UPD 3: Structures
Actual structure is :
type BannerSerializer struct {
ID int
Name string
DisplayInfo string
Format formatSerializer
Weight float32
Application int
Url string
Referrer string
}
Then i trying this structure:
type BannerSerializer struct {
ID int
Name string
DisplayInfo json.RawMessage
Format formatSerializer
Weight float32
Application int
Url string
Referrer string
}
DisplayInfo serialize as base64 string (or like base64, don't know)
Use a pointer to json.RawMessage:
type Data struct {
Obj *json.RawMessage
}
Playground: http://play.golang.org/p/Qq9IUBDLzJ.
Assuming you have access to change models.Model, you can create your own type with a custom Unmarshaler that just returns the raw string:
type JSONString string
func (s JSONString) MarshalJSON() ([]byte, error) {
return []byte(s), nil
}
Working example:
package main
import (
"encoding/json"
"fmt"
)
type JSONString string
func (s JSONString) MarshalJSON() ([]byte, error) {
return []byte(s), nil
}
type Model struct {
ID int
Name string
DisplayInfo JSONString
}
func main() {
data := []byte(`{
"ID":9,
"Name":"120 №1",
"DisplayInfo":"{\"path\": \"http://path/to/img.png\"}"
}`)
var obj Model
err := json.Unmarshal(data, &obj)
if err != nil {
panic(err)
}
// Here comes your code
js, err := json.Marshal(obj)
if err != nil {
panic(err)
}
fmt.Println(string(js))
}
Output:
{"ID":9,"Name":"120 №1","DisplayInfo":{"path":"http://path/to/img.png"}}
Playground: http://play.golang.org/p/6bcnuGjlU8
You'd have to unmarshal it, here's an example:
var data []*struct {
ID int
DisplayInfo string
}
if err := json.Unmarshal([]byte(j), &data); err != nil {
log.Fatal(err)
}
for _, d := range data {
var displayInfo struct{ Path string }
if err := json.Unmarshal([]byte(d.DisplayInfo), &displayInfo); err != nil {
log.Fatal(err)
}
fmt.Println(d.ID, displayInfo.Path)
}
playground