Last active
August 29, 2015 14:07
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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