From 1613e3ea5bd2dae11ab03ccf6d1d5ab853f8bf7d Mon Sep 17 00:00:00 2001 From: andmag <andmag@stud.ntnu.no> Date: Mon, 14 Oct 2019 20:53:57 +0200 Subject: [PATCH] Optimalization and commenting --- cmd/main.go | 3 ++ country.go | 106 +++++++++++++++++++++++++------------------------ diagnostics.go | 23 ++++++----- func.go | 28 +++++++++++++ species.go | 81 +++++++++++++++++++++++-------------- struct.go | 11 ++--- uptime.go | 4 +- 7 files changed, 158 insertions(+), 98 deletions(-) create mode 100644 func.go diff --git a/cmd/main.go b/cmd/main.go index d7e4c84..a2b44d8 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -10,7 +10,10 @@ import ( func main() { + // start-time assignment1.Init() + + // opens a port port := os.Getenv("PORT") if port == "" { port = "8080" diff --git a/country.go b/country.go index fd64c49..155a5f1 100644 --- a/country.go +++ b/country.go @@ -7,91 +7,93 @@ import ( "strings" ) -func replyCountry(w http.ResponseWriter, r *http.Request, url string, url2 string) { +// sends a request to the api and decodes the response into the country struct +func countryRequest(url string, c *http.Client, country *Country) { - http.Header.Add(w.Header(), "content-type", "application/json") + // sends a request for country and gets the response + resp := doRequest(url, c) - req, err := http.NewRequest(http.MethodGet, url, nil) - if err != nil { - fmt.Println("Error", err) - } - - client := http.DefaultClient - resp, err := client.Do(req) + // decodes the response into the struct + err := json.NewDecoder(resp.Body).Decode(&country) if err != nil { - fmt.Println("Error", err) + fmt.Println("Error", err.Error()) } + // closes the body defer resp.Body.Close() - - country := &Country{} - - json.NewDecoder(resp.Body).Decode(country) - - replySpeciesCountry(w, r, url2, country) - - json.NewEncoder(w).Encode(country) - } -func replySpeciesCountry(w http.ResponseWriter, r *http.Request, url string, country *Country) { +// sends a request to the api and decodes the respone into the structs +func speciesInCountryRequest(url string, c *http.Client, country *Country) { - req, err := http.NewRequest(http.MethodGet, url, nil) - if err != nil { - fmt.Println("Error", err) - } - - client := http.DefaultClient - resp, err := client.Do(req) - if err != nil { - fmt.Println("Error", err) - } - - defer resp.Body.Close() + // sends a request for species in a country and gets the response + resp := doRequest(url, c) + // array of results structs type Result Results + // empty result struct var nameAndKey = &Result{} - err2 := json.NewDecoder(resp.Body).Decode(nameAndKey) - if err2 != nil { - fmt.Println("Error", err2.Error()) + // decodes the response into the array of results + err := json.NewDecoder(resp.Body).Decode(nameAndKey) + if err != nil { + fmt.Println("Error", err.Error()) } + // closes the body + defer resp.Body.Close() + + // slice of species and speciesKey var spec []string var specKey []int - for k, v := range nameAndKey.Result { - fmt.Println(k) + // appends species and speciesKey to a list so we get two lists, one for species and one for speciesKey + for _, v := range nameAndKey.Result { spec = append(spec, v.Species) specKey = append(specKey, v.SpeciesKey) - } + // puts the lists in the country struct country.Species = spec country.SpeciesKey = specKey - } -// HandlerCountry dskjfhskjfhk +// HandlerCountry function: handles the country endpoint func HandlerCountry(w http.ResponseWriter, r *http.Request) { - APIURL := "https://restcountries.eu/rest/v2/alpha/" + http.Header.Add(w.Header(), "content-type", "application/json") - //SJEKK LENGDE 4 + APIURL := "https://restcountries.eu/rest/v2/alpha/" + // gets the query we want and splits the string into parts + urlQuery := r.URL.RawQuery parts := strings.Split(r.URL.Path, "/") - if len(parts) != 5 || parts[1] != "conservation" || parts[2] != "v1" || parts[3] != "country" || parts[4] == "" { - status := http.StatusBadRequest - http.Error(w, "Expecting format /conservation/v1/country/'AlphaCode'", status) - return - } - + /* + if len(parts) != 5 || parts[1] != "conservation" || parts[2] != "v1" || parts[3] != "country" || parts[4] == "" { + status := http.StatusBadRequest + http.Error(w, "Expecting format /conservation/v1/country/'AlphaCode'", status) + return + } + */ + + // appends the country-code to the country api and appends country-code and limit to the species api APIURL += parts[4] - APIURL2 := "http://api.gbif.org/v1/occurrence/search?country=" - APIURL2 += parts[4] - APIURL2 += "?limit=" + APIURL2 := "http://api.gbif.org/v1/occurrence/search?country=" + parts[4] + "&" + urlQuery + + //empty country struct + country := &Country{} - replyCountry(w, r, APIURL, APIURL2) + // makes a client + client := http.DefaultClient + + // makes a request for country and species in a country and decodes everything + countryRequest(APIURL, client, country) + speciesInCountryRequest(APIURL2, client, country) + // encodes everything to the browser + err := json.NewEncoder(w).Encode(country) + if err != nil { + fmt.Println("Error", err.Error()) + } } diff --git a/diagnostics.go b/diagnostics.go index ec6b5b6..33cb93d 100644 --- a/diagnostics.go +++ b/diagnostics.go @@ -6,12 +6,7 @@ import ( "net/http" ) -// HandlerNil kjhfkerjhgk -func HandlerNil(w http.ResponseWriter, r *http.Request) { - fmt.Println("Default Handler: Invalid request received.") - http.Error(w, "Invalid request", http.StatusBadRequest) -} - +// gets the status code from the url/api func getStatusCode(URL string) int { resp, err := http.Get(URL) if err != nil { @@ -20,15 +15,21 @@ func getStatusCode(URL string) int { return resp.StatusCode } -// HandlerDiag dsjfbgdfjgb +// HandlerDiag function: handles the diag endpoint func HandlerDiag(w http.ResponseWriter, r *http.Request) { http.Header.Add(w.Header(), "content-type", "application/json") - diagnostics := &Diag{} - diagnostics.Uptime = Uptime() - diagnostics.Version = "v1" + diagnostics := &Diag{} // empty diag struct + diagnostics.Uptime = Uptime() // uptime in seconds + diagnostics.Version = "v1" // version + + // gets statuscode from the apis diagnostics.Restcountries = getStatusCode("https://restcountries.eu/") diagnostics.Gbif = getStatusCode("http://api.gbif.org/v1/") - json.NewEncoder(w).Encode(diagnostics) + // encodes everything to the browser + err := json.NewEncoder(w).Encode(diagnostics) + if err != nil { + fmt.Println("Error", err.Error()) + } } diff --git a/func.go b/func.go new file mode 100644 index 0000000..336a1cc --- /dev/null +++ b/func.go @@ -0,0 +1,28 @@ +package assignment1 + +import ( + "fmt" + "net/http" +) + +// HandlerNil function: if the user doesn't write anything valid +func HandlerNil(w http.ResponseWriter, r *http.Request) { + fmt.Println("Default Handler: Invalid request received.") + http.Error(w, "Invalid request", http.StatusBadRequest) +} + +// handles all the requests and returns the response +func doRequest(url string, c *http.Client) *http.Response { + + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + fmt.Println("Error", err) + } + + resp, err := c.Do(req) + if err != nil { + fmt.Println("Error", err) + } + + return resp +} diff --git a/species.go b/species.go index 18102e3..ae96f4d 100644 --- a/species.go +++ b/species.go @@ -7,55 +7,78 @@ import ( "strings" ) -// HandlerSpecies kdsjfhkdjghlfdkhn +// sends a request to the api and decodes the response into the species struct +func speciesRequest(url string, c *http.Client, species *Species) { + + // sends a request to the api and gets a response + resp := doRequest(url, c) + + // decodes the response into the struct + err := json.NewDecoder(resp.Body).Decode(&species) + if err != nil { + fmt.Println("Error", err.Error()) + } + + // closes the body + defer resp.Body.Close() +} + +// sends a request to the api and decodes the response into the year struct +func yearRequest(url string, c *http.Client, species *Species) { + + // sends a request to the api and gets a response + resp := doRequest(url, c) + + // empty year struct + year := &Year{} + + // decodes the response into the struct + err := json.NewDecoder(resp.Body).Decode(&year) + if err != nil { + fmt.Println("Error", err.Error()) + } + + // puts the year from the year struct into the species struct + species.Year = year.Year + + // closes the body + defer resp.Body.Close() +} + +// HandlerSpecies function: handles the species endpoint func HandlerSpecies(w http.ResponseWriter, r *http.Request) { http.Header.Add(w.Header(), "content-type", "application/json") + // empty struct that will eventually contain the species values species := &Species{} APIURL := "http://api.gbif.org/v1/species/" + // splits the url so we can append user input to the apiurl parts := strings.Split(r.URL.Path, "/") + + // checks if it is a valid path if len(parts) != 5 || parts[1] != "conservation" || parts[2] != "v1" || parts[3] != "species" || parts[4] == "" { status := http.StatusBadRequest http.Error(w, "Expecting format /conservation/v1/species/'speciesNumber'", status) return } + // Appends userinput to the apiurl APIURL += parts[4] APIURL2 := APIURL + "/name" - s := "species" - y := "year" - - replySpecies(w, r, APIURL, s, species) - replySpecies(w, r, APIURL2, y, species) - - json.NewEncoder(w).Encode(species) -} - -func replySpecies(w http.ResponseWriter, r *http.Request, url string, str string, species *Species) { - - req, err := http.NewRequest(http.MethodGet, url, nil) - if err != nil { - fmt.Println("Error", err) - } - + // makes a client client := http.DefaultClient - resp, err := client.Do(req) - if err != nil { - fmt.Println("Error", err) - } - defer resp.Body.Close() + // sends requests to the apis, and decodes everything + speciesRequest(APIURL, client, species) + yearRequest(APIURL2, client, species) - switch str { - case "species": - json.NewDecoder(resp.Body).Decode(&species) - case "year": - year := &Year{} - json.NewDecoder(resp.Body).Decode(&year) - species.Year = year.Year + // encodes species which now contains year as well + err := json.NewEncoder(w).Encode(species) + if err != nil { + fmt.Println("Error", err.Error()) } } diff --git a/struct.go b/struct.go index 75fa2f4..f5c00cb 100644 --- a/struct.go +++ b/struct.go @@ -1,6 +1,6 @@ package assignment1 -// Country dslkjfslkfjl +// Country struct: json values for a country and its species type Country struct { Code string `json:"alpha2Code"` Countryname string `json:"name"` @@ -9,17 +9,18 @@ type Country struct { SpeciesKey []int `json:"speciesKey"` } -// Name jdhgkjdng +// Both struct: json values for species and speciesKey type Both struct { Species string `json:"species"` SpeciesKey int `json:"speciesKey"` } +// Results struct: json value for result and contains both species and speciesKey type Results struct { Result []Both `json:"results"` } -// Species comment endpoint +// Species struct: json values for one specific species type Species struct { Key int `json:"key"` Kingdom string `json:"kingdom"` @@ -32,12 +33,12 @@ type Species struct { Year string `json:"year"` } -// Year lkerjgflkjtgj +// Year struct: json value for a species discovery year type Year struct { Year string `json:"bracketYear"` } -// Diag comment endpoint +// Diag struct: type Diag struct { Gbif int Restcountries int diff --git a/uptime.go b/uptime.go index de8fe30..99d4981 100644 --- a/uptime.go +++ b/uptime.go @@ -4,12 +4,14 @@ import ( "time" ) -var startTime time.Time +var startTime time.Time // to measure the time since the last service restart +// Uptime function: returns time since start time in seconds func Uptime() float64 { return time.Since(startTime).Seconds() } +// Init function: begins the time func Init() { startTime = time.Now() } -- GitLab