Convert string having json to json or struct - json

I am getting this type of response from an API:
{
"ok": true,
"response": "[
{
"Id": 163,
"Name": "Availability",
"Path": "Performance|Tier1",
"frequency": "ONE_MIN",
"Values": [
{
"startTimeInMillis": 1571314200000,
"occurrences": 1,
"current": 1,
"min": 0,
"max": 0,
"useRange": false,
"count": 1,
"sum": 1,
"value": 1,
"standardDeviation": 0
},
{
"startTimeInMillis": 1571314260000,
"occurrences": 1,
"current": 1,
"min": 0,
"max": 0,
"useRange": false,
"count": 1,
"sum": 1,
"value": 1,
"standardDeviation": 0
},
}
]
}
]
}
I want to convert this into time series format. To do so first I am trying to unmarshal the response to this struct:
type App struct{
ID string `json:"metric_id"`
Name string `json:"metric_name"`
Path string `json:"metric_path"`
Frequency string `json:"frequency"`
Values []string `json:"metric_values"`
}
I am doing this:
apprsp := App{}
fmt.Println(json.Unmarshal([]byte(ame.Response), &apprsp))
But I am getting error while json.Unmarshal.
What I am trying to do is to generate a json of format:
{'time':'value','time1':'value2'}
Where time/time1 and value/value2 is startTimeInMillis and value from values array.
What I am doing wrong while json unmarshal? What should be done to unmarshal the above data?

Your App structure is not even closely related to the json document you're trying to unmarshal. To unmarshal a json document, you have to have a Go structure that somewhat matches the structure of the underlying document.
type ResponseValue struct {
StartTime int64 `json:"startTimeMillis"`
// other elements of Values here, if you're interested in them
}
type Response struct {
Id int `json:"Id"`
Name string `json:"Name"`
Path string `json:"Path"`
Frequency string `json:"frequency"`
Values []ResponseValue `json:"Values"`
}
type Body struct {
Response []Response `json:"response"`
}
var data Body
json.Unmarshal([]byte(ame.Response),&data)
Then, you can extract the time series from data.

As the one above me just said your mapping from your json to the struct is wrong.
An easy way to find the write mapping is to use this tool https://mholt.github.io/json-to-go/
It enables you to map json to an auto generated struct.
here is your response struct
type Response struct {
ID int `json:"Id"`
Name string `json:"Name"`
Path string `json:"Path"`
Frequency string `json:"frequency"`
Values []struct {
StartTimeInMillis int64 `json:"startTimeInMillis"`
Occurrences int `json:"occurrences"`
Current int `json:"current"`
Min int `json:"min"`
Max int `json:"max"`
UseRange bool `json:"useRange"`
Count int `json:"count"`
Sum int `json:"sum"`
Value int `json:"value"`
StandardDeviation int `json:"standardDeviation"`
} `json:"Values"`
}

Related

Dynamic JSON struct in Golang doesn't behave as expected

I'm trying to create a struct with some basic fields which are always present and some optional fields which are structs by themselves.
I'm wondering why the following code:
package main
import (
"encoding/json"
"fmt"
"time"
)
type DataManagement struct {
DataManagement struct {
Type string
Asset struct {
LocalAssetUID string
Type string
}
*ContentProductionOrder
*ContentItem
TimeStamp time.Time
Hash string
}
}
type ContentProductionOrder struct {
ProductionOrderNo int
ItemNo int
StartDate time.Time
FinishDate time.Time
StatusID int
StatusDate time.Time
SourceTypeID int
TrackingID int
}
type ContentItem struct {
ItemNo int
ItemText string
Quantity int
}
func main() {
var contentItem ContentItem
contentItem.ItemNo = 123
contentItem.ItemText = "aaaaaaaa"
contentItem.Quantity = 3
var dataManagement DataManagement
dataManagement.DataManagement.Type = "asd"
dataManagement.DataManagement.Asset.LocalAssetUID = "asd"
dataManagement.DataManagement.Asset.Type = "asd"
dataManagement.DataManagement.ContentItem = &contentItem
dataManagement.DataManagement.TimeStamp = time.Now().UTC()
dataManagement.DataManagement.Hash = "123"
xy, _ := json.MarshalIndent(dataManagement, "", " ")
fmt.Println(string(xy))
xy, _ = json.MarshalIndent(contentItem, "", " ")
fmt.Println(string(xy))
}
outputs to the following:
{
"DataManagement": {
"Type": "asd",
"Asset": {
"LocalAssetUID": "asd",
"Type": "asd"
},
"ItemText": "aaaaaaaa",
"Quantity": 3,
"TimeStamp": "2009-11-10T23:00:00Z",
"Hash": "123"
}
}
{
"ItemNo": 123,
"ItemText": "aaaaaaaa",
"Quantity": 3
}
and not to:
{
"DataManagement": {
"Type": "asd",
"Asset": {
"LocalAssetUID": "asd",
"Type": "asd"
},
"ContentItem": {
"ItemNo": 123,
"ItemText": "aaaaaaaa",
"Quantity": 3
},
"TimeStamp": "2009-11-10T23:00:00Z",
"Hash": "123"
}
}
{
"ItemNo": 123,
"ItemText": "aaaaaaaa",
"Quantity": 3
}
Any ideas? It's probably pretty easy to explain; I'm not that experienced in Golang.
Here's a Playground link: https://play.golang.org/p/iRDcaRIZ_ZU
The output you are not getting which you want is because you have used embedded struct for ContentItem in DataManagement rather than field name to add to the struct.
A field declared with a type but no explicit field name is called an
embedded field. An embedded field must be specified as a type name T
or as a pointer to a non-interface type name *T, and T itself may not
be a pointer type. The unqualified type name acts as the field name.
A field declaration will sove your issue. You should change the struct DataManagement to:
type DataManagement struct {
DataManagement struct {
Type string
Asset struct {
LocalAssetUID string
Type string
}
*ContentProductionOrder // this is embedded struct
ContentItem *ContentItem
TimeStamp time.Time
Hash string
}
}
Working Code on Go Playground
For more information, Have a look at Golang Spec for Struct Types

json object with nested structures in golang

I have the following json object that I am trying to represent with Go as a type JsonObject struct
and pass it back in its original json so that I can return the json as an api endpoint. Any advice/example?
[{
"time": 173000,
"id": "VLSuEE5m1kmIhgE7ZhHDFe",
"height": "",
"DATASTRUCTURE": {
},
"language": "en",
"size": 0,
"url": "http://www.gstatic.com/play.m3u8",
"type": "vid",
"definitionid": "h264",
"reference": "PAN-EN",
"content": "This is some content",
"revisiondate": "2017-11-29T00:00:00",
"data": {
},
"id": "BBBB3424-153E-49DE-4786-013B6611BBBB",
"thumbs": {
"32": "https://www.gstatic.com/images?q=tbn:ANd9GcRj",
"64": "https://www.gstatic.com/images?q=tbn:DPd3GcRj"
},
"title": "Cafeteria",
"hash": "BBBB5d39bea20edf76c94133be61BBBB"
}]
You can use https://mholt.github.io/json-to-go/ to generate struct for the given json schema.
For example, json given in the question can be represented like:
type AutoGenerated []struct {
Time int `json:"time"`
ID string `json:"id"`
Height string `json:"height"`
DATASTRUCTURE struct {
} `json:"DATASTRUCTURE"`
Language string `json:"language"`
Size int `json:"size"`
URL string `json:"url"`
Type string `json:"type"`
Definitionid string `json:"definitionid"`
Reference string `json:"reference"`
Content string `json:"content"`
Revisiondate string `json:"revisiondate"`
Data struct {
} `json:"data"`
Thumbs struct {
Num32 string `json:"32"`
Num64 string `json:"64"`
} `json:"thumbs"`
Title string `json:"title"`
Hash string `json:"hash"`}
Hope this helps!

JSON to struct conversion

This is the struct I have:
type Resource struct {
Name string `json:"name"`
Ranges struct {
Range []struct {
Begin int `json:"begin"`
End int `json:"end"`
} `json:"range"`
} `json:"ranges,omitempty"`
Role string `json:"role,omitempty"`
Type string `json:"type"`
Scalar Scalar `json:"scalar,omitempty"`
}
I don't know how to make fields in the JSON not null. For example, struct Range like that:
{
"name": "cpus",
"ranges": {
"range": null
},
"type": "SCALAR",
"scalar": {
"value": 1
}
}, {
"name": "mem",
"ranges": {
"range": null
}
a way to do that is assign range as *string and then you should compare it with nil or not, if not nil convert it to string and marshall it again
That changes struct is resolved my problem:
type Resource struct {
Name string `json:"name"`
Ranges *Ranges `json:"ranges,omitempty"`
Role string `json:"role,omitempty"`
Type string `json:"type"`
Scalar *Scalar `json:"scalar,omitempty"`
}
assuming that you want to marshal the structs in your question and get a json output that looks like this:
{
"name": "cpus",
"ranges": {
"range": []
},
"type": "SCALAR",
"scalar": {
"value": 1
}
},
{
"name": "mem",
"ranges": {
"range": []
}
}
In golang slices [] are a reference type, that are backed by an array.
You can read up on the internals of slices here: https://blog.golang.org/go-slices-usage-and-internals
Basically the reason that you are getting null in the output is because you have not instantiated the slice, the slice is essentially a pointer, and that pointer is nil.
Create a new empty slice, like []Range{} and assign that to the field in Resource that is currently null in the json, and instead of a nil pointer, you will have an empty slice that will be marshalled as [] and not null.

How do I parse a nested array in a nested JSON object in Golang?

I have a JSON:
{
"data": [
{
"id": 1,
"values": [
[
{
"id": "11",
"keys": [
{
"id": "111"
}
]
}
]
]
}
]
}
I want to parse "values" and "keys" into structs, but I don't known what type should i use in "Data"?:
type Value struct {
Id string `json:"id"`
Keys []Key `json:"keys"`
}
type Key struct {
Id string `json:"id"`
}
type Result struct {
Data []Data `json:"data"`
}
type Data struct {
Id int `json:"id"`
Values []???? `json:"values"`
}
I would be grateful for any help. Thanks.
If you look carefully at your json. you have an array in an array...
...
"values": [
[...
If this is intended then the type of values is:
[][]Value
to represent the two arrays, else remove the array nesting and it becomes:
[]Value
Runnable Example: https://play.golang.org/p/UUqQR1KSwB
type Basic struct {
ID string `json:"id"`
}
type Inner struct {
ID string `json:"id"`
Keys []Basic `json:"keys"`
}
type Middle struct {
ID int `json:"id"`
Values []Inner `json:"values"`
}
type Final struct {
Data []Middle `json:"data"`
}

Unable to decode the JSON response

I have the following response from a graph api
{
"data": [
{
"name": "Mohamed Galib",
"id": "502008940"
},
{
"name": "Mebin Joseph",
"id": "503453614"
},
{
"name": "Rohith Raveendranath",
"id": "507482441"
}
],
"paging": {
"next": "https://some_url"
}
}
I have a struct as follows
type Item struct {
Name, Id string
}
I wanted to parse the response and get an array of Item, How do I do that?
You need to update your struct like so:
type Item struct {
Name string `json:"name"`
Id string `json:"id"`
}
and add a struct to represent the wrapper:
type Data struct {
Data []Item `json:"data"`
}
You can then use json.Unmarshal to populate a Data instance.
See the example in the docs.