Skip to content

Instantly share code, notes, and snippets.

@heyrutvik
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save heyrutvik/3e857829381c00dae73a to your computer and use it in GitHub Desktop.
Save heyrutvik/3e857829381c00dae73a to your computer and use it in GitHub Desktop.
trying my hand on Go Programming... program makes an HTTP request to the Hacker News (HN SEARCH API) and copies its response to standard output.
/*
* program takes string argument, make http GET request to
* Hacker News ( Y Combinator ) and print result on stdout.
*
* To run:
* $ go run /path/to/hacker_news.go -s "search string"
*
* NOTE: Go program without goroutines and channels is crap. I know... THIS was just for fun! ;)
*/
package main
import (
"encoding/json" // need to decode json object
"errors" // convert error string to error value
"flag" // command line arguments
"fmt" // format output string
"log" // print error on stderr
"net/http" // to make GET request
"strings" // string manipulation functions
)
// structure Response contains slice of structure Item
type Response struct {
Hits []Item
}
// structure Item will hold values of json object
// you can see the format of json object at https://hn.algolia.com/api
type Item struct {
Title string
Url string
Author string
Points int
}
func main() {
sFlag := flag.String("s", "golang", "search flag")
flag.Parse()
search := strings.Replace(*sFlag, " ", "%20", -1)
fmt.Println("Wait...\n")
items, err := Get(search)
if err != nil {
log.Fatal(err)
}
for _, item := range items {
fmt.Println(item)
}
}
// Get() takes string and returns slice of Item and error number
// Yes!.. Go function can return multiple values
func Get(search string) ([]Item, error) {
url := fmt.Sprintf("https://hn.algolia.com/api/v1/search?query=%s", search)
//fmt.Println(url)
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, errors.New(resp.Status)
}
// new(T) returns pointer of type T
r := new(Response)
err = json.NewDecoder(resp.Body).Decode(r)
if err != nil {
return nil, err
}
// make(T, size) returns type T
items := make([]Item, r.Len())
for i, child := range r.Hits {
if child.Title != "" {
items[i] = child
}
}
return items, nil
}
// String() function allows to take receiver `i Item`
// and return string as per body of function
// So, you can format output of custom Type
func (i Item) String() string {
title := fmt.Sprintf("Title:\t%s", i.Title)
url := fmt.Sprintf("Url:\t%s", i.Url)
author := fmt.Sprintf("Author:\t%s", i.Author)
points := fmt.Sprintf("Points:\t%d", i.Points)
return strings.Join([]string{title, url, author, points, ""}, "\n")
}
// Len() receives pointer of Response struct and
// return count of non-blank member Title of Item
func (r *Response) Len() (count int) {
for _, child := range r.Hits {
if child.Title != "" {
count++
}
}
return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment