mkaz.blog

Working with Go

REST API

Use the net/http standard library to create external http calls. You can combine this with the parsing of JSON to work with external APIs.

The following example pulls in data from the Reddit API to get latest posts from golang sub. The key to understanding JSON decoding is understanding the data structure you receive the data. Once data structs are mapped, it becomes relatively straight forward

package main
 
import (
    "encoding/json"
    "io/ioutil"
    "log"
    "net/http"
)
 
// create data structures to hold JSON data
// this needs to match the fields in the JSON feed
// see sample data fetch at bottom of this file
 
// create an individual entry data structure
// this does not need to hold every field, just the ones we want
type Entry struct {
    Title     string
    Author    string
    URL       string
    Permalink string
}
 
// the feed is the full JSON data structure
// this sets up the array of Entry types (defined above)
type Feed struct {
    Data struct {
        Children []struct {
            Data Entry
        }
    }
}
 
func main() {
    // url of REST endpoint we are grabbing data from
    url := "https://www.reddit.com/r/golang/new.json"
 
    // fetch url
    resp, err := http.Get(url)
    if err != nil {
        log.Fatalln("Error fetching:", err)
    }
    // defer response close
    defer resp.Body.Close()
 
    // confirm we received an OK status
    if resp.StatusCode != http.StatusOK {
        log.Fatalln("Error Status not OK:", resp.StatusCode)
    }
 
    // read the entire body of the response
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatalln("Error reading body:", err)
    }
 
    // create an empty instance of Feed struct
    // this is what gets filled in when unmarshaling JSON
    var entries Feed
    if err := json.Unmarshal(body, &entries); err != nil {
        log.Fatalln("Error decoing JSON", err)
    }
 
    // loop through the children and create entry objects
    for _, ed := range entries.Data.Children {
        entry := ed.Data
        log.Println(">>>")
        log.Println("Title   :", entry.Title)
        log.Println("Author  :", entry.Author)
        log.Println("URL     :", entry.URL)
        log.Printf("Comments: http://reddit.com%s \n", entry.Permalink)
    }
}