I am relatively new to golang, and I wanted to create a way to do concurrently call multiple URLs, and parse the JSON documents. However, I'm really unsure if I am properly using go routines and channels. At this point, I'm not sure if I am not properly "thinking in Go" or if my understanding/approach of goroutines and channels is not accurate.
Additionally, when parsing, I would like to parse the results
property from the body, which is an array, and each element in results
contains a doc
property that I'd like to filter out.
The goal is to do multiple fetches, concurrently and parse the responses for just the doc
property inside of an responses body results array.
Definitely would appreciate any insight or suggestions to understand things better. Thanks in advance.
package operations
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"
)
// CouchbaseDoc parses .doc property from sync gateway documents
type CouchbaseDoc struct {
Doc map[string]string `json:"doc"`
}
// Results deconstruct... results is a property of body, and is an array of obects
type Results struct {
Results []byte `json:"results"`
}
func createURLs(channels []string) map[string]string {
urlMap := make(map[string]string)
domain := "swap" + strings.TrimSpace(os.Getenv("env"))
bucket := strings.TrimSpace(os.Getenv("bucket"))
for _, doctype := range channels {
urlMap[doctype] = fmt.Sprintf("https://%s.endpoint.com/%s/_changes?filter=sync_gateway/bychannel&channels=%s&include_docs=true", domain, bucket, doctype)
}
return urlMap
}
func getChangesFeed(url string, ch chan map[string]string) {
resp, _ := http.Get(url)
body, _ := ioutil.ReadAll(resp.Body)
go parseBody(body, ch)
}
func parseBody(body []byte, ch chan map[string]string) {
var results Results
var doc CouchbaseDoc
json.Unmarshal(body, &results)
json.Unmarshal(results.Results, &doc)
// write to responses
ch <- doc.Doc
}
func fetchDocs(channels []string) {
urls := createURLs(channels)
// Response channel is where all go routines will do the dirty
responses := make(chan map[string]string)
for _, url := range urls {
go getChangesFeed(url, responses)
}
// Read from responses channel
docs := <-responses
for doc := range docs {
fmt.Println(doc) // This should print results ??
}
}