I'm starting to learn Golang and I would like to know how to get a json response by calling an url, if you could give me an example it would be great in order to guide myself.
2 Answers
Here's a simple example to get you started. Instead of a map[string]interface{} you should consider making a struct to hold the result of your request.
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
func main() {
resp, err := http.Get("http://api.geonames.org/citiesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demo")
if err != nil {
log.Fatal(err)
}
var generic map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&generic)
if err != nil {
log.Fatal(err)
}
fmt.Println(generic)
}
4 Comments
rog
Note that this answer is wrong in a couple of significant ways, as I've pointed out in another answer here.
Eve Freeman
I was just going for a quick and dirty single request program.
cppiscute
@EveFreeman....I get "map[message:401 Unauthorized]"...I know this is because of the User token value that I need to pass along with URL ....May I know how to pass the info along with URL ?
Eve Freeman
@statisticalbeginner check out headers examples. See "For control over HTTP client headers, redirect policy, and other settings, create a Client" from golang.org/pkg/net/http
I'd write a little helper function to do it:
// getJSON fetches the contents of the given URL
// and decodes it as JSON into the given result,
// which should be a pointer to the expected data.
func getJSON(url string, result interface{}) error {
resp, err := http.Get(url)
if err != nil {
return fmt.Errorf("cannot fetch URL %q: %v", url, err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected http GET status: %s", resp.Status)
}
// We could check the resulting content type
// here if desired.
err := json.NewDecoder(resp.Body).Decode(result)
if err != nil {
return fmt.Errorf("cannot decode JSON: %v", err)
}
return nil
}
A full working example can be found here: http://play.golang.org/p/b1WJb7MbQV
Note that it is important to check the status code as well as the Get error, and the response body must be closed explicitly (see the documentation here: http://golang.org/pkg/net/http/#Get)
1 Comment
Eve Freeman
I've also had trouble with responses not closing fast enough when requesting at a high rate--ended up doing ioutil.ReadAll() after Decode(). Not sure if it's supposed to be strictly necessary, but I would run out of fds without it, even with
defer resp.Body.Close().