How to extract specific JSON data - json

I do not know how to select specific JSON data.
How can I change this code so that I have just the id, and none of the other response data?
I read online, and apparently I need to use a struct? I am unsure of how to approach this problem.
package main
import(
"fmt"
"io"
"log"
"net/http"
)
func get_single_product() {
res, err := http.Get("https://api.pro.coinbase.com/products/UNI-USD")
if err != nil {
log.Fatal(err)
}
data, err := io.ReadAll(res.Body)
res.Body.Close()
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", data)
}
func main() {
// CALL GET PRODUCTS FUNCTION
get_single_product()
}
This Returns...
{
"id":"UNIUSD",
"base_currency":"UNI",
"quote_currency":"USD",
"base_min_size":"0.1",
"base_max_size":"200000",
"quote_increment":"0.0001",
"base_increment":"0.000001",
"display_name":"UNI/USD",
"min_market_funds":"1.0",
"max_market_funds":"100000",
"margin_enabled":false,
"post_only":false,
"limit_only":false,
"cancel_only":false,
"trading_disabled":false,
"status":"online",
"status_message":""
}

You can use the encoding/json package to decode your json data to an object. Just define the fields you are interested in the object and it will only read out those. Then create a decoder with json.NewDecoder().
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
type Response struct {
ID string `json:"id"`
}
func main() {
res, err := http.Get("https://api.pro.coinbase.com/products/UNI-USD")
if err != nil {
log.Fatal(err)
}
var response Response
json.NewDecoder(res.Body).Decode(&response)
fmt.Println(response.ID)
}
// Output
UNI-USD
See also this question: How to get JSON response from http.Get

Related

Unmarshal JSON to map[any]any

I want to unmarshal a JSON object to a map of map[any]any. This yields the error json: cannot unmarshal object into Go value of type map[interface {}]interface {}. Why is this not possible?
package main
import (
"encoding/json"
"fmt"
)
func main() {
bytes := []byte(`{"sendMsg":{"user":"ANisus","msg":"Trying to send a message"},"say":"Hello"}`)
var bytesInMap map[any]any
err := json.Unmarshal(bytes, &bytesInMap)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("Hello World %s", bytesInMap)
}

Can get value of JSON in Go

I'm new in Go. I'm trying to read a JSON file and get a part of it for then operate with the values obtained.
My JSON is in the file example.json:
{"results":[{"statement_id":0,"series":[{"name":"cpu/node_utilization","columns":["time","distinct"],"values":[[10,1],[11,3],[13,5]]}]}]}
So what I would like to get is the "values" for get the sum of all the elements. In this case: 1+3+5
Here is the code that I have. I'm available to get the results, but then I don't manage to get series.
Here is the code that I have:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
)
func main() {
// Open our jsonFile
jsonFile, err := os.Open("example.json")
// if we os.Open returns an error then handle it
if err != nil {
fmt.Println(err)
}
fmt.Println("Successfully Opened example.json")
// defer the closing of our jsonFile so that we can parse it later on
defer jsonFile.Close()
byteValue, _ := ioutil.ReadAll(jsonFile)
var all_data map[string]interface{}
json.Unmarshal([]byte(byteValue), &all_data)
fmt.Println(all_data["results"])
}
I've tried diferent solutions like
all_data["results"].(map[string]interface{})["series"])
But the problem is that the map is in an array, and I don't know how to solve it.
Using interfaces and map
package main
import (
"encoding/json"
"fmt"
)
func main() {
byteValue := []byte(`{"results":[{"statement_id":0,"series":[{"name":"cpu/node_utilization","columns":["time","distinct"],"values":[[10,1],[11,3],[13,5]]}]}]}`)
var all_data map[string][]interface{}
json.Unmarshal([]byte(byteValue), &all_data)
fmt.Println("result:", all_data["results"])
for _, r := range all_data["results"] {
s := r.(map[string]interface{})
fmt.Println("series:", s["series"])
w := s["series"].([]interface{})
for _, x := range w {
y := x.(map[string]interface{})
fmt.Println(y)
z := y["values"].([]interface{})
fmt.Println("values:", z)
for _, v := range z {
u := v.([]interface{})
fmt.Println(u)
for _, i := range u {
val := i.(float64)
fmt.Println(val)
}
}
}
}
}
I have solved defining an Struct.
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
)
type AutoGenerated struct {
Results []struct {
StatementID int `json:"statement_id"`
Series []struct {
Name string `json:"name"`
Columns []string `json:"columns"`
Values [][]int `json:"values"`
} `json:"series"`
} `json:"results"`
}
func main() {
// Open our jsonFile
jsonFile, err := os.Open("example.json")
// if we os.Open returns an error then handle it
if err != nil {
fmt.Println(err)
}
fmt.Println("Successfully Opened example.json")
// defer the closing of our jsonFile so that we can parse it later on
defer jsonFile.Close()
byteValue, _ := ioutil.ReadAll(jsonFile)
all_data := AutoGenerated{}
json.Unmarshal([]byte(byteValue), &all_data)
fmt.Println(all_data.Results[0].Series[0].Values)
}
I have used this web to generate automatically the Struct providing the JSON structure

How to use switch in GO with json keys?

Here is an example of POST request body:
{"action":"do_something","id":"001"}
I took an example of simple json parser
package main
import (
"encoding/json"
"fmt"
"net/http"
)
type some_json struct {
Action string `json:"action"`
Id string `json:"id"`
}
func jsonparse(rw http.ResponseWriter, request *http.Request) {
decoder := json.NewDecoder(request.Body)
var post_data some_json
err := decoder.Decode(&post_data)
if err != nil {
panic(err)
}
switch ***WHAT_SHOULD_BE_HERE???*** {
default :
fmt.Fprintf(w,"WRONG PARAM")
case "some_thing":
fmt.Fprintf(w,post_data.Id + "\n\n")
}
}
func main() {
http.HandleFunc("/", jsonparse)
http.ListenAndServe(":8080", nil)
}
I already know how to switch cases from form values, but
how to switch cases of json key values?
I am not sure what you want to switch, but i think that you just need to erase the () so Action is not a function call anymore
Be careful maybe your error is that u mixed up the strings
in JSON: "do_something"
in case: "some_thing"
You can copy following code to playground
package main
import (
"encoding/json"
"fmt"
"strings"
)
type some_json struct {
Action string `json:"action"`
Id string `json:"id"`
}
func jsonparse() {
r := strings.NewReader("{\"action\":\"do_something\",\"id\":\"001\"}")
decoder := json.NewDecoder(r)
var post_data some_json
err := decoder.Decode(&post_data)
if err != nil {
panic(err)
}
switch post_data.Action {
default:
fmt.Println( "WRONG PARAM")
case "do_something":
fmt.Println( post_data.Id+"\n\n")
}
}
func main() {
jsonparse()
}

Cannot unmarshal object into Go value of type []uint8

I am fairly new to Go. I have the following code:
package main
import (
"encoding/json"
"fmt"
)
func main() {
byt := []byte(`{"num":6.13,"strs":["a","b"]}`)
dat := []byte(`{"num":7.13,"strs":["c","d"]}`)
if err := json.Unmarshal(byt, &dat); err != nil {
panic(err)
}
fmt.Println(dat)
}
Getting the error:
cannot "unmarshal object into Go value of type []uint8".
How can I fix this please?
You have 2 JSON inputs, and you're trying to unmarshal one into the other. That doesn't make any sense.
Model your JSON input (the object) with a type (struct), and unmarshal into that. For example:
type Obj struct {
Num float64 `json:"num"`
Strs []string `json:"strs"`
}
func main() {
byt := []byte(`{"num":6.13,"strs":["a","b"]}`)
var obj Obj
if err := json.Unmarshal(byt, &obj); err != nil {
panic(err)
}
fmt.Println(obj)
}
Output (try it on the Go Playground):
{6.13 [a b]}
I think you meant to do something like this:
package main
import (
"encoding/json"
"fmt"
)
func main() {
var dat interface{}
byt := []byte(`{"num":6.13,"strs":["a","b"]}`)
if err := json.Unmarshal(byt, &dat); err != nil {
panic(err)
}
fmt.Println(dat)
}
What you were trying to do makes no sense, since you're trying to unmarshal two JSON objects one into another.

How to fetch values from JSON in golang

i have following piece of code which calls the yahoo finance api to get the stock values for given stock symbol.
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
)
//Response structure
type Response struct {
Query struct {
Count int `json:"count"`
Created string `json:"created"`
Lang string `json:"lang"`
Results struct {
Quote []struct {
LastTradePriceOnly string `json:"LastTradePriceOnly"`
} `json:"quote"`
} `json:"results"`
} `json:"query"`
}
func main() {
var s Response
response, err := http.Get("http://query.yahooapis.com/v1/public/yql?q=select%20LastTradePriceOnly%20from%20yahoo.finance.quote%20where%20symbol%20in%20(%22AAPL%22,%22FB%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys")
if err != nil {
fmt.Printf("%s", err)
os.Exit(1)
} else {
defer response.Body.Close()
contents, err := ioutil.ReadAll(response.Body)
json.Unmarshal([]byte(contents), &s)
fmt.Println(s.Query.Results.Quote)
if err != nil {
fmt.Printf("%s", err)
os.Exit(1)
}
fmt.Printf("%s\n", string(contents))
}
}
fmt.Println(s.Query.Results.Quote) is giving me a multi value array since Quote is a array of structure. For eg: [{52.05},{114.25}]
How should i split it in a single value in golang ?
For eg: 52.05
114.25
Help is highly appreciated.
Thanks
I am new to golang and not aware of many data structures. But i figured out how to get the single value out of array of structure.
fmt.Println(s.Query.Results.Quote[0].LastTradePriceOnly)
this worked for me..I only have to iterate this in a loop to fetch all values.
Thanks.