15

Hi everyone I'm trying to see what the proper way of accessing fields of a json object from a http.get request in go.

I first do an http.get call get the JSON and then print it (which works) but is there a way to access just a field?

for example:

response, err:= http.Get("URL")
//Error checking is done between
contents, err:=ioutil.Readall(response.Body)

//Now at this point I have a json that looks like
{"id": "someID", 
"name": "someName", 
"test": [{"Name":"Test1", 
          "Result": "Success"},
         {"Name":"Test2", 
          "Result": "Success"},
         {...},
]}

Is there a way to only print the "test" of the Json? What is the proper way of accessing that field?

1
  • you will have to parse json using encoding/json package. Commented Feb 26, 2016 at 19:52

6 Answers 6

17

Use encoding/json package to Unmarshal data into struct, like following.

type Result struct {
    ID   string        `json:"id"`
    Name string        `json:"name"`
    Test []interface{} `json:"test"`
}

var result Result
json.Unmarshal(contents, &result)
fmt.Println(result.Test)

You can also parse Test to specific struct.

Sign up to request clarification or add additional context in comments.

3 Comments

Ohhh I see, what did you mean parse Test to a specific struct?
You can define a struct named Test and in Result struct use Test []Test instead of Test []interface{}
Struct fields that have a json tag (all of them, in the example proposed here) need to be exported, meaning they need to start with a capital letter. More info at Exported identifiers
14

Same as the previous answer, use encoding/json package to Unmarshal data. But if you don't want to specify the structure, you could use map[string]interface/bson.M{} to receive the data, and get the field, then cast into types your want.

m := make(map[string]interface{})
err := json.Unmarshal(data, &m)
if err != nil {
    log.Fatal(err)
}
fmt.Println(m["id"])

Comments

3

You may want to try gabs container, if you are not sure how depth JSON hierarchy can be. Have a look at below resources

https://github.com/Jeffail/gabs https://godoc.org/github.com/Jeffail/gabs

Comments

2

If you just want to access one field then you can use the jsonq module https://godoc.org/github.com/jmoiron/jsonq

For your example you could get the test object with code similar to

jq.Object("test")

Where jq is a jsonq query object constructed from your JSON above (see the godoc page for instructions on how to create a query object from a JSON stream or string).

You can also use this library for retrieving specific String, Integer, Float and Bool values at an arbitrary depth inside a JSON object.

Comments

1

You may check this https://github.com/valyala/fastjson

s := []byte(`{"foo": [123, "bar"]}`)
    fmt.Printf("foo.0=%d\n", fastjson.GetInt(s, "foo", "0"))

    // Output:
    // foo.0=123

Comments

0

Since you are starting with a URL, Decode is a better option than Unmarshal:

package main

import (
   "encoding/json"
   "net/http"
)

func main() {
   r, e := http.Get("https://github.com/manifest.json")
   if e != nil {
      panic(e)
   }
   defer r.Body.Close()
   var s struct { Name string }
   json.NewDecoder(r.Body).Decode(&s)
   println(s.Name == "GitHub")
}

https://golang.org/pkg/encoding/json#Decoder.Decode

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.